Haskell在读取数据之前关闭连接

时间:2015-06-21 02:18:47

标签: haskell

我写了以下程序:

{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE BangPatterns #-}
import Control.Exception (bracket)
import Control.Monad (forM)
import Control.Monad.IO.Class (MonadIO(liftIO))
import Data.List.Split (chunksOf)
import qualified Database.MongoDB as M

import qualified Data.Text as T

db :: M.Action IO a -> IO a
db action = do
    pipe <- M.connect (M.host "127.0.0.1")
    res <- M.access pipe M.master "haskell" action
    M.close pipe
    return res

main = do
    let docs = (flip map) [0..199999] $ \i ->
            ["name" M.=: (T.pack $ "name " ++ (show i))]
    ids <- forM (chunksOf 50000 docs) $ \chunk ->
      db $ M.insertAll "bigCollection" chunk

    cur <- db $ M.find $ (M.select [] "bigCollection") {M.limit = 100000, M.batchSize = 100000}
    returnedDocs <- db $ drainCursor cur

    putStrLn $ show $ length returnedDocs

drainCursor :: M.Cursor -> M.Action IO [M.Document]
drainCursor !cur = drainCursor' cur []
  where
    drainCursor' cur res  = do
      batch <- M.nextBatch cur
      if null batch
        then return res
        else drainCursor' cur (res ++ batch)

在插入所有数据后,它会停留在等待来自服务器的数据上。我认为这是因为它在读取数据之前关闭了连接。我试过BangPatterns和seq函数,括号函数,但没有成功。只有当我保持连接打开时(通过注释掉M.close)它才有效。有人可以推荐我如何规避这种情况吗?

提前致谢。

1 个答案:

答案 0 :(得分:2)

要扩展@ chi的评论,您可能想要替换

cur <- db $ M.find $ (M.select [] "bigCollection")
                     {M.limit = 100000, M.batchSize = 100000}
returnedDocs <- db $ drainCursor cur

通过

returnedDocs <- db $ do
    cur <- M.find $ (M.select [] "bigCollection")
                    {M.limit = 100000, M.batchSize = 100000}
    drainCursor cur

我从未使用过mongoDB,但我确信数据库游标只能在创建它的连接中使用。