Я пишу сценарии CGI в Haskell. Когда пользователь нажимает "отправить", программа Haskell запускается на сервере, обновляет (то есть считывает, обрабатывает, перезаписывает) файл состояния. Чтение, а затем перезаписи иногда вызывает проблемы с ленивым IO, так как мы можем сгенерировать большой выходной префикс, прежде чем мы закончим чтение ввода. Хуже того, пользователи иногда отказываются от кнопки отправки и одновременно запускают два экземпляра процесса, борясь за один и тот же файл!
Какой хороший способ реализовать
transactionalUpdate :: FilePath -> (String -> String) -> IO ()
где функция (& lsquo; update & rsquo;) вычисляет новое содержимое файла из старого содержимого файла? Небезопасно предполагать, что & lsquo; update & rsquo; является строгим, но можно предположить, что он является полным (надежность функций частичного обновления является бонусом). Транзакции могут быть предприняты одновременно, но никакая транзакция не должна обновляться, если файл был написан кем-либо еще с момента его чтения. Это нормально для транзакции, чтобы прервать в случае конкуренции за доступ к файлам. Мы можем считать источником уникальных для системы временных имен файлов.
Моя текущая попытка записывается во временный файл, а затем используется команда копирования системы для перезаписывания. Это, похоже, касается ленивых проблем с ИО, но это не ударяет меня так же безопасно от рас. Есть ли проверенная и проверенная формула, которую мы могли бы просто бутылить?