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