Принудительная оценка на ленивых IO - PullRequest
1 голос
/ 01 апреля 2012

Моя программа читает строку из сетевого сокета и записывает ее на диск. Поскольку строки могут быть очень длинными и строки имеют ужасную производительность, я начал использовать ленивые байтовые строки. Теперь кажется, что Haskell будет проходить мимо hClose на дескрипторе файла диска, фактически не сбрасывая всю байтовую строку на диск, делая так:

  • открыть файл для записи
  • записать байтовую строку в файл с hPut
  • закрыть файл
  • открыть файл для чтения

обычно приводит к openFile: resource busy (file is locked).

Можно ли принудительно выполнить оценку и дождаться записи всей байтовой строки перед закрытием файла, поэтому я могу быть уверен, что файл действительно закрыт после этой операции?

Ответы [ 2 ]

0 голосов
/ 13 апреля 2012

Так как единственный другой ответ - это «использовать что-то другое», я публикую свое собственное решение. Использование этой функции после hClose приведет к зависанию потока, пока не будет выполнена отложенная запись.

waitForLazyIO location = do
    t <- liftIO $ try $ openFile location AppendMode
    handle t
    where
        handle (Right v) = hClose v
        handle (Left e)
            -- Add some sleep if you expect the write operation to be slow.
            | isAlreadyInUseError e = waitForLazyIO location
            | otherwise = throwError $ show e
0 голосов
/ 01 апреля 2012

Попробуйте использовать строгий ввод-вывод со строгими байтовыми строками вместо ленивого ввода-вывода и ленивых байтовых строк.

Если это окажется слишком неэффективным, попробуйте использовать канал илианалогичная упаковка.

...