记录forkIO / catch块

时间:2017-03-09 18:32:22

标签: haskell monad-transformers io-monad

我正在建立一个仆人应用程序,使用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 ()

AppMonadLog (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 ThreadIdcatchIsh :: (MonadIO m, Exception e) => m a -> (e -> m a) -> m a会对我有帮助吗? - 我想是的 - 在我的案例中,我可以在liftIO内调用logErrorApp清理和mkReport部分。
  • 是否有办法在提升的部件中“解除”monad变压器堆栈的属性?

0 个答案:

没有答案