【发布时间】:2016-04-07 14:12:36
【问题描述】:
更新
我已经用一个从脚手架创建的实际项目简化了这个演示 - 你可以在这里查看:https://github.com/tetigi/yesod-bug-test
按照自述文件设置 repo 并复制问题!谢谢:)
原帖
我最近一直在尝试使用 yesod 创建一个简单的网站 - 在一个特定的处理程序中,它会进行几次 runDB 调用(选择一些值并将其插入到大约 200 个项目的数据库中)。但是,在中等负载(例如在浏览器中快速重新加载页面)时,页面会开始挂起。
在进行一些调试时,我发现 yesod 应用似乎没有及时释放与数据库池的连接,最终等待它们释放。为了证实这一点,我发现了以下其他内容:
- 将 DB 池减少到 2 后,我只需单击几下就冻结了
- 默认值 (10) 在单击大约 5 秒后冻结
- 将 DB 池增加到 100 可以让我获得更长的点击时间,最多可以达到大约 10-15 秒的快速点击时间
- 无论我使用的是 postgres 还是 sqlite,问题都是一样的
- 在 postgres 中,可以看到“COMMIT”事务随着时间的推移而堆积
- 这些交易最终会随着时间的推移而消失,网站会再次响应
这里有什么我遗漏的吗?网页没有做任何复杂的事情,如下面的 sn-p 所示。有任何想法吗?就目前而言,在我找到解决此问题的方法之前,该网站将无法供多个用户使用!
我正在按照文档中的建议通过堆栈使用标准的脚手架 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")
【问题讨论】: