Yesod中的共享数据

时间:2014-01-03 06:43:58

标签: haskell yesod

我想在Yesod中的请求之间共享一些数据。在我的情况下,数据是MVar (Data.Map Text ReadWriteLock),但我不认为这里共享数据的格式太重要了。

在Foundation.hs中,有一条评论说我可以向App添加字段,每个处理程序都可以访问那里的数据。这似乎是我可以用来在不同处理程序之间共享数据的方法。我一直在浏览Yesod书,但我找不到从App获取数据的任何示例。

  • 如何从处理程序中访问新创建的字段?

我认为这可能是STM的一个很好的用例。我可以分享TVar (Data.Map Text ReadWriteLock)。但是创建TVar 会将TVar包裹在STM monad中。我可能会弄错,但对我来说,整个Yesod“主循环”似乎需要在STM monad中运行。

  • 在这里使用STM是一个可行的选择吗?任何人都可以详细说明如何实现这一目标吗?

2 个答案:

答案 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")