我想在Yesod中的请求之间共享一些数据。在我的情况下,数据是MVar (Data.Map Text ReadWriteLock)
,但我不认为这里共享数据的格式太重要了。
在Foundation.hs中,有一条评论说我可以向App添加字段,每个处理程序都可以访问那里的数据。这似乎是我可以用来在不同处理程序之间共享数据的方法。我一直在浏览Yesod书,但我找不到从App获取数据的任何示例。
我认为这可能是STM的一个很好的用例。我可以分享TVar (Data.Map Text ReadWriteLock)
。但是创建TVar
会将TVar
包裹在STM
monad中。我可能会弄错,但对我来说,整个Yesod“主循环”似乎需要在STM monad中运行。
答案 0 :(得分:2)
这个tutorial for building a file server with Yesod很好地展示了如何使用STM访问共享数据。相关部分从第2部分开始。
答案 1 :(得分:1)
要详细说明pxqr的评论,你想做这样的事情。
在您的Foundation.hs文件中(假设您使用yesod init
启动了项目。)
data App = App
{ ... other fields
, shared :: TVar Int -- New shared TVar field
}
然后在您创建App
实例的Application.hs文件中。
makeFoundation conf = do
.... snip .....
tv <- newTVarIO 0 -- Initialize your TVar
let logger = Yesod.Core.Types.Logger loggerSet' getter
foundation = App conf s manager logger tv -- Add TVar here
return foundation
然后在你的处理程序中使用TVar
getHomeR :: Handler Html
getHomeR = do
app <- getYesod -- Get the instance of App
x <- liftIO $ atomically $ do -- Read and update the TVar value.
val <- readTVar (shared app)
writeTVar (shared app) (val + 1)
return val
(formWidget, formEnctype) <- generateFormPost sampleForm
let submission = Nothing :: Maybe (FileInfo, Text)
handlerName = "getHomeR" :: Text
defaultLayout $ do
aDomId <- newIdent
-- Use the TVar value (increments on each page refresh).
setTitle $ fromString (show x)
$(widgetFile "homepage")