我正在建立一个仆人应用程序,使用GETting url开始使用震动生成报告。直到请求记录这些东西,这有点像魅力,但现在我遇到了问题。
一个处理程序start
开始生成报告 - 因为这可能需要一段时间 - 我立即返回200,并产生一个进程来完成实际工作,日志记录由logging-effect
完成。
我的start
处理程序的简化版本如下所示
start :: IO () -> App ()
start mkReport = do
logInfo $ PP.text "Report generation started"
_ <- liftIO . forkIO $ catch mkReport caught
where caught e = do logError $ PP.text "Report generation crashed: " <>
{-^^^^^^^-} (PP.text . T.pack $ displayException e)
cleanup
return ()
App
是MonadLog (WithTimestamp (WithSeverity Doc))
的一个实例 - 所以logInfo
工作正常。 ✔
准确地说App
是以下新类型:
newtype App a =
App { _runApp :: ReaderT Environment (ExceptT ServantErr
(LoggingT (WithTimestamp (WithSeverity Doc)) IO)) a
} deriving ( Functor, Applicative, Monad, MonadReader Environment,
, MonadError ServantErr, MonadLog (WithTimestamp (WithSeverity Doc)))
但是当我尝试在logError
部分内调用caught
时 - 除了删除生成/临时文件的cleanup
操作之外,我收到编译错误。 ✘
No instance for MonadLog (WithSeverity Doc) IO arising from a use of 'logError'...
这是正确的,IO
没有这样的实例,谢谢ghc告诉我并且没有在运行时崩溃!
这些是我正在经历的想法 - 也许有人看到了错误的假设:
forkIO
来分叉生成报告吗?forkIOish :: MonadIO m => m () -> m ThreadId
和catchIsh :: (MonadIO m, Exception e) => m a -> (e -> m a) -> m a
会对我有帮助吗? - 我想是的 - 在我的案例中,我可以在liftIO
内调用logError
时App
清理和mkReport部分。