Yesod scaffolded site缓慢释放数据库池连接

时间:2016-01-04 00:09:21

标签: haskell yesod

更新

我已经通过脚手架创建的实际项目简化了演示 - 您可以在此处查看:https://github.com/tetigi/yesod-bug-test

按照自述文件设置回购并复制问题!谢谢:))

原始帖子

我最近一直在尝试使用yesod创建一个简单的网站 - 在一个特定的处理程序中,它会进行一些runDB调用(选择并将一些值插入到~200项DB中)。但是,在中等负载上,例如在浏览器中快速重新加载页面,页面开始挂起。

做一些调试,我发现似乎yes应用程序没有及时释放与数据库池的连接,最终等待它们释放。为了解决这个问题,我发现了以下其他事项:

  • 将数据库池减少到2后,只需点击几下即可冻结
  • 默认(10)在点击
  • 约5秒后冻结
  • 将数据库池增加到100给了我更长的点击时间,快速点击最多约10-15秒
  • 无论我使用的是postgres还是sqlite
  • ,问题都是一样的
  • 在postgres中,可以看到“COMMIT”交易随着时间的推移而累积
  • 这些交易最终会随着时间的推移而消失,网站会再次响应

这里有什么我想念的吗?网页没有做任何复杂的事情,因为下面的代码段会显示。有任何想法吗?就目前而言,该网站将无法用于多个用户,直到找到解决方法!

我正在使用标准的scaffolded yesod应用程序,如文档中所推荐的那样。

干杯!

示例处理程序代码(删节)

getCompareR :: Handler Html
getCompareR = do

    -- Get all entities from the db. Throws error if < 2 elems in the DB.
    entities <- fmap (\xs -> assert (length xs >= 2) xs) $ runDB $ selectList [] []

    -- Pick an entity at random
    Entity _ thisThingEntity <- liftIO $ runRVar (choice entities) DevRandom

    -- Pull out everything NOT the thing we just picked
    otherEntities <- runDB $ selectList [ComparisonHash !=. (comparisonHash thisThingEntity)] []

    -- Pick one at random
    Entity _ thatThingEntity <- liftIO $ runRVar (choice otherEntities) DevRandom

    -- Some stuff including some inserts
    -- ...
    -- ...

    runDB $ sequence [update thisId [ComparisonElo =. thisElo], update thatId [ComparisonElo =. thatElo]]

    -- Start laying out the webpage
    defaultLayout $ do
        -- Fill in the rest with compare.hamlet
        $(widgetFile "compare")

1 个答案:

答案 0 :(得分:3)

问题出在Data.Random中 - 用以下内容替换choice调用:

import System.Random (randomRIO)

...

 -- Pick an entity at random
randomInt1 <- liftIO $ randomRIO (0, length entities -1) 
let Entity _ thisThingEntity = entities !! randomInt1

修正了一切,我们不再慢下来。不确定为什么Data.Random会这样做,但至少现在可以正常工作了!

另一个值得注意的事情是 - Mac OS X上没有这个问题,只有Linux风格(CentOS,Arch,Ubuntu就是我们尝试过的)