module Control.Immortal.Worker(
workerWith
, worker
, isolate
, isolate_
) where
import Control.Concurrent (threadDelay)
import Control.DeepSeq
import Control.Exception.Safe (SomeException, catchDeep)
import Control.Monad.IO.Unlift
import Control.Monad.Logger
import Data.Text (pack)
import qualified Control.Immortal as I
workerWith :: (MonadUnliftIO m, MonadLogger m)
=> (String -> SomeException -> m ())
-> String
-> (I.Thread -> m ())
-> m I.Thread
workerWith logthem lbl f = I.createWithLabel lbl $ \thread ->
I.onUnexpectedFinish thread (either (logthem lbl) (const $ pure ())) (f thread)
worker :: (MonadUnliftIO m, MonadLogger m) => String -> (I.Thread -> m ()) -> m I.Thread
worker = workerWith $ \lbl e -> do
logErrorN $ "Worker " <> pack lbl <> " exit with: " <> (pack . show) e
liftIO $ threadDelay 1000000
isolate :: (MonadUnliftIO m, MonadLogger m, NFData a) => String -> a -> m a -> m a
isolate title a0 ma = do
run <- askRunInIO
liftIO $ catchDeep (run ma) $ \(e :: SomeException) -> run $ do
logErrorN $ "Isolated action " <> pack title <> " failed: " <> (pack . show) e
pure a0
isolate_ :: (MonadUnliftIO m, MonadLogger m) => String -> m () -> m ()
isolate_ lbl = isolate lbl ()