add a finalizer to streamLogFile

Sponsored-by: Dartmouth College's DANDI project
This commit is contained in:
Joey Hess 2022-09-23 13:49:01 -04:00
parent 8718125ae4
commit ed8afacc39
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
2 changed files with 13 additions and 8 deletions

View file

@ -113,25 +113,30 @@ fullLines = go []
let (l, b') = L.splitAt n b let (l, b') = L.splitAt n b
in go (l:c) (L.drop 1 b') in go (l:c) (L.drop 1 b')
-- | Streams lines from a log file, and then empties the file at the end. -- | Streams lines from a log file, passing each line to the processor,
-- and then empties the file at the end.
-- --
-- If the action is interrupted or throws an exception, the log file is -- If the processor is interrupted or throws an exception, the log file is
-- left unchanged. -- left unchanged.
-- --
-- Does nothing if the log file does not exist. -- There is also a finalizer, that is run once all lines have been
-- streamed. It is run even if the log file does not exist. If the
-- finalizer throws an exception, the log file is left unchanged.
-- --
-- Locking is used to prevent writes to to the log file while this -- Locking is used to prevent writes to to the log file while this
-- is running. -- is running.
streamLogFile :: FilePath -> RawFilePath -> (String -> Annex ()) -> Annex () streamLogFile :: FilePath -> RawFilePath -> Annex () -> (String -> Annex ()) -> Annex ()
streamLogFile f lck a = withExclusiveLock lck $ bracketOnError setup cleanup go streamLogFile f lck finalizer processor =
withExclusiveLock lck $ bracketOnError setup cleanup go
where where
setup = liftIO $ tryWhenExists $ openFile f ReadMode setup = liftIO $ tryWhenExists $ openFile f ReadMode
cleanup Nothing = noop cleanup Nothing = noop
cleanup (Just h) = liftIO $ hClose h cleanup (Just h) = liftIO $ hClose h
go Nothing = noop go Nothing = finalizer
go (Just h) = do go (Just h) = do
mapM_ a =<< liftIO (lines <$> hGetContents h) mapM_ processor =<< liftIO (lines <$> hGetContents h)
liftIO $ hClose h liftIO $ hClose h
finalizer
liftIO $ writeFile f "" liftIO $ writeFile f ""
setAnnexFilePerm (toRawFilePath f) setAnnexFilePerm (toRawFilePath f)

View file

@ -34,7 +34,7 @@ streamSmudged :: (Key -> TopFilePath -> Annex ()) -> Annex ()
streamSmudged a = do streamSmudged a = do
logf <- fromRepo gitAnnexSmudgeLog logf <- fromRepo gitAnnexSmudgeLog
lckf <- fromRepo gitAnnexSmudgeLock lckf <- fromRepo gitAnnexSmudgeLock
streamLogFile (fromRawFilePath logf) lckf $ \l -> streamLogFile (fromRawFilePath logf) lckf noop $ \l ->
case parse l of case parse l of
Nothing -> noop Nothing -> noop
Just (k, f) -> a k f Just (k, f) -> a k f