My program reads a line from a network socket and writes it to disc. Since lines can be really long and strings had terrible performance I started using lazy byte strings. Now it seems that Haskell will go past hClose
on disc file handle without actually flushing whole byte string to disc, so doing:
hPut
usually results in openFile: resource busy (file is locked)
.
Is it possible to enforce evaluation and wait for the whole byte string to be written before closing the file, so I can be sure that the file is actually closed after that operation?
Since the only other answer is of the "use something else" variety I'm posting my own solution. Using this function after hClose
will hang the thread until lazy write is done.
waitForLazyIO location = do
t <- liftIO $ try $ openFile location AppendMode
handle t
where
handle (Right v) = hClose v
handle (Left e)
-- Add some sleep if you expect the write operation to be slow.
| isAlreadyInUseError e = waitForLazyIO location
| otherwise = throwError $ show e