-
-
Notifications
You must be signed in to change notification settings - Fork 22
Open
Labels
good for new contributorsPull requests welcome!Pull requests welcome!new exampleThis issue is about writing a new example program.This issue is about writing a new example program.
Description
I like concurrent logging as the subject as a Phrasebook example because it's a common need and a good excuse to concisely put together a lot of topics.
Here's some code that comes straight out of the repo for the Type Classes server. It probably contains a few too many topics and needs to be significantly simplified and better focused.
- Starting threads with
withAsync - Concurrent queues
TQueue - Catching exceptions with
catchAny - Cleaning up after interrupts with
finally - Introducing strictness with
($!)
import Control.Concurrent.Async (withAsync)
import Control.Concurrent.STM
import Control.Exception.Safe (Exception (displayException), catchAny, finally)
import Control.Monad (forever)
import Control.Monad.Trans.Cont
import Data.Text (Text)
import qualified Data.Text as Text
import qualified Data.Text.IO as Text
import System.IO (stderr)
data Log =
Log
{ logText :: Text -> IO ()
, logString :: String -> IO ()
}
withLogging :: ContT a IO Log
withLogging = ContT \continue ->
do
q <- atomically newTQueue
let
logText msg = atomically (writeTQueue q $! msg)
logString = logText . Text.pack
l = Log {..}
withAsync (runLogger q) \_ -> (continue l)
runLogger :: TQueue Text -> IO ()
runLogger q = finally runForever runUntilEmpty
where
runForever = forever $ atomically (readTQueue q) >>= write
runUntilEmpty =
atomically (tryReadTQueue q) >>=
\case
Nothing -> return ()
Just msg -> write msg *> runUntilEmpty
write msg = Text.hPutStrLn stderr msg
recover :: Log -> IO a -> IO (Maybe a)
recover log a = catchAny (fmap Just a) (\e -> logException log e *> return Nothing)
logException :: Exception e => Log -> e -> IO ()
logException log e = logString log (displayException e)Metadata
Metadata
Assignees
Labels
good for new contributorsPull requests welcome!Pull requests welcome!new exampleThis issue is about writing a new example program.This issue is about writing a new example program.