我有以下代码行使用aeson
来序列化IntMap
并将JSON保存到磁盘,所有这些都在子线程上:
import Data.Aeson (encode, toJSON)
import Data.Conduit (($$), (=$), yield)
import qualified Data.ByteString.Lazy as BL (toStrict)
import qualified Data.Conduit.Binary as CB (sinkFile)
import qualified Data.Conduit.List as CL (map)
-- ...
forkIO . runResourceT $ yield (toJSON intMap) $$ CL.map (BL.toStrict . encode) =$ CB.sinkFile file
我想确保此代码不会被任何异步异常中断。我担心中断可能会导致磁盘上的数据不完整/损坏。
在这种情况下,我可以做些什么来确保免受异步异常的影响?即使main
想要终止,是否可以确保允许子线程完成?
谢谢!
答案 0 :(得分:3)
我建议使用另一种与 conduit 无关的技术:
rename
是专为它设计的,在this question上应该有所帮助。使用此序列,无论发生什么,目标文件将保持不变或将包含完全写入磁盘的新数据。如果序列由于某种原因突然中断,它只会留下过时的临时文件。
unix Haskell库引入fsync
only in version 2.7.1.0,但您可以自行添加调用。请参阅this module中的Ganeti project(在BSD2下获得许可)。特别是
foreign import ccall "fsync" fsync :: CInt -> IO CInt
fsyncFile :: FilePath -> IO ()
fsyncFile path =
bracket (openFd path ReadOnly Nothing defaultFileFlags) closeFd callfsync
where
callfsync (Fd fd) = throwErrnoPathIfMinus1_ "fsyncFile" path $ fsync fd