Yesod 脚手架站点释放数据库池连接缓慢

Yesod scaffolded site slow to release database pool connection

更新

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

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

原版POST

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

调试了一下,发现yesod app好像没有及时释放到数据库池的连接,一直在等待释放。为了证实这一点,我发现了以下其他内容:

我在这里遗漏了什么吗?该网页不会做任何复杂的事情,如下面的代码片段所示。有任何想法吗?目前,在我找到解决此问题的方法之前,该网站将无法供多个用户使用!

我正在按照文档中的建议通过堆栈使用标准脚手架 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")

问题出在 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 是我们尝试过的)