服务器端会话尚未成为Snap Framework的一部分。有没有办法添加某种服务器端状态?
让我假装我想为每个HTTP请求增加一个计数器。我该怎么做?
答案 0 :(得分:8)
上述答案是正确的,但它没有涉及一些实际问题。
首先是服务器重启。如果您的存储不仅仅是缓存,那么它需要在服务器重新启动时保持持久。
其次是代码重新加载。 Snap的未来版本,从0.3开始(可能在12月初到期)将在开发使用中重新加载动态代码。就开发速度而言,这是一个巨大的优势,但它使服务器本地状态成为一项有趣的心理练习。如果程序员更改了类型/初始化/服务器本地状态,则需要重新初始化。那里有一些巨大的工程挑战。
当我编写0.3的动态重载代码时,我一直在努力解决这个问题。然后我看了其他平台。 PHP?在外部存储所有内容(数据库,内存缓存等)。根本没有内存中的交叉请求存储。 Ruby on Rails?相同。
当结合第一期中固有的挑战时,我得出结论,除了可能的缓存优化之外,服务器应该是无状态的。保留为其设计的库/外部进程的持久性问题。
所以我设计了生产和开发加载器使用的通用接口(一个使用静态加载,另一个使用动态加载)来获取3个函数:初始化函数,清理函数和使用由返回的状态返回的处理程序。初始化功能。在生产模式下,编译为在服务器启动时调用initialize,在服务器关闭时进行清理。在开发模式下,它编译为:对于每个请求,动态加载所有3,然后运行init,handler,cleanup。显然,任何国家都不会以这种方式交叉请求。
然后我的答案变成:通过一些具有内置持久性的机制进行交叉请求存储,并让服务器状态成为它的接口。如果你想在进程内工作,可以使用像happstack-state或sqlite这样的东西,如果你想在本地进程外工作,可以使用数据库或其他外部存储。
另外,由于添加了MonadSnap接口,因此在Snap 0.3中管理“全局”资源(如连接池等)也变得更加容易。
答案 1 :(得分: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
初始化站点时初始化mvar。希望这会有所帮助。
答案 2 :(得分:1)
我找到了两个与会话相关的包:
snap-auth 由Snap Framework团队制作,或至少由其作者/ contirbutor(Ozgun Ataman)制作。它针对身份验证和会话管理。使用ByteString到ByteString的映射完成会话管理,这意味着您只能将已经序列化的数据存储到ByteString:
type Session = Map ByteString ByteString
另一方面, mysnapsession 允许您使用任意类型为会话建模。但是,Map
类型的会话有一些辅助函数。更多细节here。作者Chris Smith也是Snap Framework项目的一部分。