Ссылочная прозрачность и mmap в Haskell

Я надеялся использовать System.INotify и System.IO.MMap вместе, чтобы смотреть для модификации файлов, а затем быстро выполнять различия для отправки патчей по сети. Однако в документации для System.IO.MMap есть несколько предупреждений о ссылочной прозрачности:

В документации указано

Безопасно только mmap файл, если вы знаете, что являетесь единственным пользователем. В противном случае ссылочная прозрачность может быть или не быть скомпрометирована. К сожалению, семантика сильно отличается между операционными системами.

Значения, возвращаемые MMap, являются IO ByteString, конечно, когда я использую это значение с putStr, я ожидаю другой результат каждый раз? Я полагаю, что автор означает, что значение может меняться во время операции ввода-вывода, например putStr и сбой?

СТАРТ-РЕДАКТИРОВАНИЕ: Подумайте об этом, я думаю, ответ на эту часть вопроса несколько очевиден... Если значение изменяется в любое время после его распаковки, это будет проблематично.

do 
  v <- mappedValue :: IO ByteString
  putStr v
  putStr v  -- Expects the same value of v everywhere

END-OF-РЕДАКТИРОВАТЬ

Нельзя ли получить какую-либо блокировку в отображаемой области или в файле?

В качестве альтернативы можно ли написать функцию copy :: IO ByteString -> IO ByteString, которая безопасно выполнит моментальный снимок файла в его текущем состоянии?

Ответ 1

Я думаю, что автор означает, что значение может меняться даже внутри поднятой функции, которая может просматривать ее как обычный ByteString (без ввода-вывода).

Отображаемый файл с памятью является областью памяти. Не имеет смысла копировать его содержимое взад и вперед по соображениям производительности (в противном случае можно было бы просто выполнить простой поток на основе ввода-вывода). Таким образом, ByteString, который вы получаете, является вживую.

Если вы хотите иметь моментальный снимок, просто используйте потоковый ввод-вывод. Это то, что читает файл: создает моментальный снимок файла в памяти! Я предполагаю, что альтернативой будет использование интерфейса ForeignPtr, который не несет предупреждения ссылочной прозрачности. Я не знаком с ForeignPtrs, поэтому я не могу гарантировать, что он сработает, но он выглядит многообещающим, и я бы его исследовал.

Вы также можете попробовать позвонить map id в свою ByteString, но не гарантируется, что вы получите копию, отличную от оригинала.

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