Атомарность с openTempFile - PullRequest
0 голосов
/ 11 мая 2011

У меня есть следующая функция:

safeWrite :: Text -> IO ()
safeWrite c = bracket (openTempFile "/tmp" "list.tmp")
    (\(path, h) -> hClose h
      >> copyFile path dataFile
      >> removeFile path)
    (\(_, h) -> TI.hPutStr h c)

У меня сложилось впечатление, что это будет безопасно, копирование не произойдет, если в любой момент возникнут ошибки, а исходный файл все еще будет пригоден для использования. Однако буквально вчера у меня появился пустой файл, и я понятия не имею, куда его посмотреть. Программа работала более месяца без каких-либо сбоев, что указывает на какой-то угловой случай, о котором я не думал.

Гарантирует ли метод атомарность, то есть ошибка в другом месте, а если нет, то почему? Что я должен сделать, чтобы гарантировать атомарность?

1 Ответ

2 голосов
/ 11 мая 2011

Ваше определение mkTemp является атомарным относительно исключений из Haskell . Если есть исключение, он напечатает сообщение об ошибке (оставив файл там).

  • Это не атомарно по отношению к файловой системе Unix - другие программы могут перезаписать тот же файл
  • Он не очищается в случае сбоя.

Вы можете сделать немного больше для очистки, по желанию удаляя файл, если есть исключение, или просто используя предоставленную (атомарную) функцию mkTemp:

или используя слой posix:

...