Haskell MongoDB驱动程序可能出现死锁

时间:2013-12-09 10:02:37

标签: mongodb haskell concurrency database-connection

从ghc 7.4升级到ghc 7.6后,我注意到我的一些数据库调用减速了40倍。为了调查,我写了一些简单的测试,我的代码基本上是:

timeFetch :: Pipe -> UUID.UUID -> IO ()
timeFetch pipe uuid' = do
  lrResult <- access pipe master "MyDB" $ (findOne (select ["uid" =: ["$in" =: [(uuidToBUUID uuid')]]] "uidCollection") :: Action IO (Maybe Document))
  case lrResult of
    Right _ -> do
      printCrntTm "Right has result"
      timeFetch pipe uuid'
    Left _  -> printCrntTm "Left err"

printCrntTm只使用描述字符串打印当前时间,uuidToBUUID是因为Data.UUID是与Mongo的Data.Bson UUID类型不同的类型。 timeFetch本身递归地无限地调用自己。

所以在GHC 7.6中,我看到了:

2013-12-09 09:35:52.307008 UTC Right has result
2013-12-09 09:35:52.348027 UTC Right has result
2013-12-09 09:35:52.389047 UTC Right has result
2013-12-09 09:35:52.430041 UTC Right has result
2013-12-09 09:35:52.471031 UTC Right has result
2013-12-09 09:35:52.512061 UTC Right has result
2013-12-09 09:35:52.553043 UTC Right has result

但是在GHC 7.4中,我看到了:

2013-12-09 09:36:38.109144 UTC Right has result
2013-12-09 09:36:38.110297 UTC Right has result
2013-12-09 09:36:38.111248 UTC Right has result
2013-12-09 09:36:38.112398 UTC Right has result
2013-12-09 09:36:38.113185 UTC Right has result
2013-12-09 09:36:38.114248 UTC Right has result

这相当于1毫秒vs 40毫秒!!!我还需要提一下7.6版本有一次,我得到了:*** Exception: thread blocked indefinitely in an MVar operation(但再也没有),这让我想到了我的主要问题。

我挖了一下,我想知道Database.MongoDB中的这些代码行是否是罪魁祸首:

newCursor :: (MonadIO m, MonadBaseControl IO m) => Database -> Collection -> BatchSize -> DelayedBatch -> Action m Cursor
-- ^ Create new cursor. If you don't read all results then close it. Cursor will be closed automatically when all results are read from it or when eventually garbage collected.
newCursor db col batchSize dBatch = do
    var <- newMVar dBatch
    let cursor = Cursor (db <.> col) batchSize var
    mkWeakMVar var (closeCursor cursor)
    return cursor
#if !MIN_VERSION_base(4,6,0)
  where mkWeakMVar = addMVarFinalizer
#endif

GHC 7.6中的base模块是4.6.x.x而在GHC 7.4中。它是4.5.x.x。

我不是Haskell的专家,也不是并发编程;任何人都可以说明我所看到的40倍缓慢是否可以解释?是否需要调试Database.MongoDB库代码?提前谢谢!

1 个答案:

答案 0 :(得分:1)

MongoDB驱动程序肯定非常慢。可能有很多悬而未决的成果,只需要拆除管道连接系统就可以更快。