UPDATE
我已经通过脚手架创建的实际项目简化了演示 - 您可以在这里查看:https://github.com/tetigi/yesod-bug-test
按照README设置repo并复制问题!谢谢 :)
原始邮政
我最近一直在尝试使用yesod创建一个简单的网站 - 在一个特定的处理程序中,它会进行一些runDB调用(选择并将一些值插入到~200项DB中).但是,在中等负载上,例如在浏览器中快速重新加载页面,页面开始挂起.
做一些调试,我发现似乎yes应用程序没有及时释放与数据库池的连接,最终等待它们发布.为了解决这个问题,我发现了以下其他事情:
这里有什么我想念的吗?网页没有做任何复杂的事情,因为下面的代码段会显示.有任何想法吗?目前,该网站将无法用于多个用户,直到我找到解决方法!
我正在使用标准的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")
Run Code Online (Sandbox Code Playgroud)
问题出在 Data.Random 中 - 将调用替换choice
为以下内容:
import System.Random (randomRIO)
...
-- Pick an entity at random
randomInt1 <- liftIO $ randomRIO (0, length entities -1)
let Entity _ thisThingEntity = entities !! randomInt1
Run Code Online (Sandbox Code Playgroud)
修复了所有问题,我们不再放慢速度。不太清楚为什么 Data.Random 会这样做,但至少现在它可以工作了!
另一个值得注意的有趣的事情 - 这个问题不存在于 Mac OS X 上,只存在于 Linux 版本上(我们尝试过 CentOS、Arch、Ubuntu)