haskell - 如何使用 yesod 按请求缓存?

标签 haskell caching yesod

我正在尝试使用 cached 函数来防止不同小部件和处理程序中的多个数据库查询:

newtype CachedBobId key
    = CachedBobId { unCachedBobId :: key }
    deriving Typeable

getBob' :: Handler BobId
getBob' = do
    uncle <- runInputGet $ ireq textField "bobsuncle"
    (Entity bob _) <- runDB $ getBy404 $ UniqueBob uncle
    return bob

getBob :: Handler BobId
getBob = do
    a <- getBob'
    let b = return $ CachedBobId a
    c <- cached b
    return $ unCachedBobId c

在某个小部件中:

renderDerp :: Widget
renderDerp = do
    --these are used in the shakespeare files
    lolBob <- handlerToWidget $ getBob
    nutherBob <- handlerToWidget $ getBob
    $(widgetFile "test")

这可以编译,但获取 ID 的查询仍然运行多次。

我做错了什么?或者是否有更好的方法只获取 bob 一次并在每个处理程序和小部件中使用他?

最佳答案

我对 Yesod 还很陌生,但我认为你只需要调整 getBob

getBob :: Handler BobId
getBob = unCachedBobId <$> cached (CachedBobId <$> getBob')

问题是您当前的 getBob函数开始其 do阻止 a <- getBob' 。请记住 do block 序列单子(monad) Action ,所以你实际上最终调用 getBob'每次第一件事getBob叫做。具有讽刺意味的是,完成此操作后,您将创建一个处理程序的缓存版本,该处理程序返回您刚刚从 getBob' 获得的内容。 ,但最终只查询该缓存版本一次(随后使用 c <- cached b ),然后它就超出了范围,垃圾收集器得到了它。

在我上面介绍的解决方案中,您可以包装任何 getBob'给你CachedBobId 。然后,您传递该处理程序 CachedBobId <$> getBob' :: Handler (CachedBobId BobId) , 至cached ,它会返回另一个处理程序 cached (CachedBobId <$> getBob')类型相同,但带有缓存。最后,您提取缓存处理程序提供的任何内容以获取 Handler BobId .

关于haskell - 如何使用 yesod 按请求缓存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33655589/

相关文章:

php - 如何使用 Zend_Cache 标识符?

jquery - 当 jQuery.html() 时从缓存加载 .js 文件

ruby-on-rails - Controller 中的查询缓存

haskell - Yesod,如何从 Javascript/Julius 中的 JSON 数据生成类型安全链接

haskell - 如何在 REPL 中运行 Yesod 的数据库操作?

list - 使用 foldr 将列表分成指定大小的子列表

haskell - 如何在 Helm 中合并信号?

haskell - 在 Haskell 中解构元组时,可以在哪里使用元素?

haskell : Minimum position

haskell - 在 Yesod 中发送 301 重定向