fast-logger 3.2.8 → 3.2.9
raw patch · 4 files changed
+42/−4 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- ChangeLog.md +5/−0
- System/Log/FastLogger/SingleLogger.hs +16/−3
- fast-logger.cabal +1/−1
- test/FastLoggerSpec.hs +20/−0
ChangeLog.md view
@@ -1,3 +1,8 @@+## 3.2.9++* The writer thread of SingleLogger survives write errors such as+ ENOSPC and EPIPE. The failed messages are dropped.+ ## 3.2.8 * Take another road under the Windows native I/O manager
System/Log/FastLogger/SingleLogger.hs view
@@ -7,6 +7,7 @@ import Control.Concurrent (MVar, forkIO, newEmptyMVar, putMVar, takeMVar) import Control.Concurrent.STM+import qualified Control.Exception as E import GHC.Conc.Sync (labelThread) import System.Log.FastLogger.FileIO@@ -58,9 +59,21 @@ go (F mvar cont : msgs) = do putMVar mvar () if cont then go msgs else return False- go (L msg@(LogStr len _) : msgs)- | len <= bufsize = writeLogStr buf fdref msg >> go msgs- | otherwise = writeBigLogStr fdref msg >> go msgs+ go (L msg@(LogStr len _) : msgs) = do+ dropOnSyncException $+ if len <= bufsize+ then writeLogStr buf fdref msg+ else writeBigLogStr fdref msg+ go msgs++-- If writing fails (e.g. ENOSPC or EPIPE), the message is dropped+-- so that the writer thread keeps running and flushes do not block.+dropOnSyncException :: IO () -> IO ()+dropOnSyncException act = act `E.catch` handler+ where+ handler e = case E.fromException e of+ Just (E.SomeAsyncException _) -> E.throwIO e+ Nothing -> return () ----------------------------------------------------------------
fast-logger.cabal view
@@ -1,6 +1,6 @@ cabal-version: >=1.10 name: fast-logger-version: 3.2.8+version: 3.2.9 license: BSD3 license-file: LICENSE maintainer: Kazu Yamamoto <kazu@iij.ad.jp>
test/FastLoggerSpec.hs view
@@ -17,6 +17,11 @@ #endif import Data.String (IsString (fromString)) import System.Directory (doesFileExist, removeFile)+#if !defined(mingw32_HOST_OS)+import qualified GHC.IO.FD as FD+import GHC.IO.IOMode (IOMode (ReadMode))+#endif+import System.Timeout (timeout) import Text.Printf (printf) import Test.Hspec@@ -52,6 +57,7 @@ describe "fastlogger 1" $ do it "maintains the ordering of log messages" logOrdering+ it "survives write errors" survivesWriteErrors tempFile :: FilePath tempFile = "test/temp.txt"@@ -113,3 +119,17 @@ where mktag :: Int -> String mktag t = "thread id: " <> show t <> " "++survivesWriteErrors :: IO ()+#if defined(mingw32_HOST_OS)+survivesWriteErrors = pendingWith "POSIX only"+#else+survivesWriteErrors = do+ -- Writing to a read-only FD fails with EBADF.+ (fd, _) <- FD.openFile "LICENSE" ReadMode False+ lgrset <- newFDLoggerSet 512 (Just 1) Nothing fd+ let msg = toLogStr (BS.replicate 100 'x') <> "\n"+ mapM_ (\_ -> pushLogStr lgrset msg) [1 .. 100 :: Int]+ timeout 3000000 (flushLogStr lgrset) `shouldReturn` Just ()+ timeout 3000000 (rmLoggerSet lgrset) `shouldReturn` Just ()+#endif