yellowtides / owenbot-hs

A utility bot written in Haskell for the Edinburgh Informatics Class of ‘24’s main messaging platform (Discord server).
https://yellowtid.es/owenbot-hs/
BSD 3-Clause "New" or "Revised" License
8 stars 7 forks source link

Double Posting in Hall of Fame #27

Open yutotakano opened 3 years ago

yutotakano commented 3 years ago

Double posting in the Hall of Fame channel is becoming a very very frequent problem (1 in 2 at least), and I've been manually deleting many -- if it's a race condition, it's way too frequent and should be fixed immediately.

jacobjwalters commented 3 years ago

This is indeed a race condition, and occurs due to the fact that each time we receive an event (in this case, a reaction being added), we spawn a new thread. These (non-atomically) read the entire db of HoF'd posts, check if the given post is in it, and if not prepends it and posts an entry in the HoF channel.

The issue here is that the file read and search operation is slow (and lazy), so if events come in fast enough we can effectively get a TOCTOU situation on our hands.

The best way I can immediately think of to solve this is to store a semaphore for the file in an MVar to ensure we can atomically check for the entry's existence in the db. It might be nice to provide this functionality in Utils such that it can be used elsewhere, as I imagine this type of bug could come up again. It seems that System.Posix.Semaphore provides it for any POSIX-compliant system (which we currently assume anyways), so that should be a nice solution. It automatically handles thread safety for us too!

This could also be mitigated by keeping a copy of the db in an MVar also (which I plan to implement with the config/db system rewrite).