如何处理或避免BlockedIndefinitelyOnSTM异常?

原位

我花了很多时间对正在处理的应用程序中的问题进行故障排除。该应用程序是一个Web应用程序,使用scotty公开REST端点。它使用aTVar来保持其状态,该状态通过STM a前端层触发的动作进行更新

由于此应用程序基于事件源原理,因此STM事务完成由业务层生成的任何事件都将存储到EventStore(当前是一个简单的平面文件...)中。这是相关的代码片段:

newtype (EventStore m) => WebStateM s m a = WebStateM { runWebM :: ReaderT (TVar s) m a }

  deriving (Functor,Applicative,Monad, MonadIO, MonadTrans, MonadReader (TVar s))


    applyCommand :: (EventStore m, Serializable (Event a)) =>
                    Command a                                    
                 -> TVar s
                 -> WebStateM s m (Event a) 
    applyCommand command = \ v -> do
      (e, etype :: EventType s) <- liftIO $ atomically $ actAndApply v
      storeEvent e etype
      return e
      where
        actAndApply =  \ v -> do
          s <- readTVar v
          let view = getView s
          let e  = view `act` command
          let bv = view `apply` e

          modifyTVar' v (setView bv)

          return (e, getType view)

这可以完美地工作,直到storeEvent函数中出现错误为止这个函数负责用适当的类型序列化事件,并且我在序列化例程中犯了一个(严重)错误,导致某种类型的错误导致无限循环!然后突然,我cabal test开始挂起并因超时而失败(我使用wreq作为客户端库来测试REST服务)。我花了几个小时才能确定服务器端的实际错误:tests: thread blocked indefinitely in an STM transaction怀疑序列化程序,我又花了两个小时才找出罪魁祸首并解决问题。

尽管我当然对错误负责(我应该更彻底地测试我的序列化例程!),但是我发现它很容易引起误解。我想更好地了解此错误的来源以及如何防止它。我已经阅读了爱德华·杨(Edward Yang)关于该主题帖子,以及该邮件主题,但是我必须承认导致观察到此错误的逻辑事件链对我来说并不完全清楚。

我想我理解applyCommand由scotty生成的线程调用死于评估时启动的某些异常(堆栈耗尽吗?)storeEvent,但是我不明白这与事务成为垃圾有关

数学兰花

唯一的例外一个线程试图做一个交易,并且命中retry,这将重新运行该交易改变的东西时。但是它等待更改的内容不再在任何地方引用,因此重试永远不会发生。那是一个错误。基本上,该线程现在已挂起。

可以想象某个地方的某个线程应该对此进行更新TVar,但是它由于异常而死亡,从而删除了对该位置的最后引用TVar并引发了异常。

我就是这么想的如果没有看到整个应用程序,就很难确定。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何处理或避免BlockedIndefinitelyOnSTM异常?

来自分类Dev

EJB如何处理异常?

来自分类Dev

如何处理gem的异常

来自分类Dev

Deno:如何处理异常

来自分类Dev

如何处理arraylist异常?

来自分类Dev

如何处理登录异常?

来自分类Dev

如何处理ContentProvider的异常?

来自分类Dev

如何处理 HttpAsyncClient 异常

来自分类Dev

如何处理或避免C ++ 11 <regex>匹配函数(第28.11节)带来的异常?

来自分类Dev

如何处理 <DataColumn> Widget 的动态列表以避免 Flutter DataTable Widget 中的 RenderFlex 异常?

来自分类Dev

如何处理JavaCPP避免数据复制?

来自分类Dev

jQuery未处理的异常如何处理此异常

来自分类Dev

如何处理Asmack中的临时异常

来自分类Dev

MEF ComposeParts。如何处理插件异常

来自分类Dev

如何处理gitpython clone异常?

来自分类Dev

使用DTO时如何处理异常

来自分类Dev

如何处理JSF多个意外异常?

来自分类Dev

如何处理ExecutorService任务引发的异常?

来自分类Dev

如何处理硒中的异常?

来自分类Dev

如何处理Task中的不同异常?

来自分类Dev

如何处理令牌不匹配异常

来自分类Dev

如何处理异常的TCP断开连接?

来自分类Dev

如何处理来自Singleton Java的异常?

来自分类Dev

浏览器如何处理异常?

来自分类Dev

如何处理嵌套作业的异常?

来自分类Dev

@Consumes批注引发异常,如何处理

来自分类Dev

如何处理来自角色异常的错误

来自分类Dev

如何处理页面外的异常?

来自分类Dev

使用DTO时如何处理异常