如何使用Snap Framework维护服务器端状态?

gaw*_*awi 5 haskell session-state haskell-snap-framework

服务器端会话不是Snap Framework的一部分.有没有办法添加某种服务器端状态?

让我假装我想为每个HTTP请求增加一个计数器.我该怎么办?

Car*_*arl 8

上述答案是正确的,但它没有涉及一些实际问题.

首先是服务器重启.如果您的存储不仅仅是缓存,则需要在服务器重新启动时保持持久性.

第二是代码重新加载.Snap的未来版本,从0.3开始(可能在12月初到期)将在开发使用中重新加载动态代码.这在开发速度方面是一个巨大的优势,但它使服务器本地状态成为一项有趣的心理练习.如果程序员更改了类型/初始化/服务器本地状态,则需要重新初始化.那里有一些巨大的工程挑战.

当我编写0.3的动态重载代码时,我在这个问题上挣扎了一段时间.然后我看了其他平台.PHP?在外部存储所有内容(数据库,内存缓存等).根本没有内存中的交叉请求存储.Ruby on Rails?相同.

结合第一期中固有的挑战,我得出结论,除了可能的缓存优化之外,服务器应该是无状态的.保留为其设计的库/外部进程的持久性问题.

所以我设计了生产和开发加载器使用的通用接口(一个使用静态加载,另一个使用动态加载)来获取3个函数:初始化函数,清理函数和使用初始化函数返回的状态的处理程序.在生产模式下,编译为在服务器启动时调用initialize,在服务器关闭时进行清理.在开发模式下,它编译为:对于每个请求,动态加载所有3,然后运行init,handler,cleanup.显然,任何国家都不会以这种方式交叉请求.

然后我的答案变成:通过一些具有内置持久性的机制进行交叉请求存储,并让服务器状态成为它的接口.如果要在进程内工作,请使用happstack-state或sqlite之类的东西,如果要在本地进程外工作,请使用数据库或其他外部存储.

同样作为补充说明,由于添加了MonadSnap接口,在Snap 0.3中管理"全局"资源(如连接池等)也变得更加容易.


小智 3

最简单的方法是将状态放在 mvar 后面:

fooHandler :: MVar Int -> Snap ()
fooHandler mvar = do
    x <- liftIO $ modifyMVar mvar $ \y -> let y'=y+1 in (y',y')
    writeBS $ S.pack $ "Incremented counter to: " ++ show x
Run Code Online (Sandbox Code Playgroud)

站点初始化时初始化 mvar。希望这可以帮助。

  • 请注意,您可能需要改为编写 `\y -&gt; let y'=y+1 in y' \`seq\` (y',y')` 。否则,您可能会在 mvar 中存储未评估的 thunk,而不是值。或者使用 [strict-concurrency](http://hackage.haskell.org/package/strict-concurrency) 包中的 strict mvar。 (2认同)