Even without -threaded
the Haskell runtime will have several "green threads" running cooperatively. You need to use Control.Concurrent
to limit access to the file because you cannot have several threads writing to it at once.
The easiest way is to have an MVar ()
in your Server
and have each request "take" the unit from the MVar
before opening the file and then put it back after the file operation has been completed. You can use bracket
to ensure that the lock is released even if writing the file fails. E.g. something like
import Control.Concurrent
import Control.Exception (bracket_)
type Lock = MVar ()
data Server = Server { fileLock :: Lock }
saveRegistration :: Registration -> Lock -> IO ()
saveRegistration r lock = bracket_ acquire release updateFile where
acquire = takeMVar lock
release = putMVar lock ()
updateFile =
withFile "registrations.txt" AppendMode (\h -> hPutStrLn h $ "+" ++ show r)