簡體   English   中英

如何使用Snap Framework維護服務器端狀態?

[英]How do I maintain a server-side state with Snap Framework?

服務器端會話不是Snap Framework的一部分。 有沒有辦法添加某種服務器端狀態?

讓我假裝我想為每個HTTP請求增加一個計數器。 我該怎么辦?

上述答案是正確的,但它沒有涉及一些實際問題。

首先是服務器重啟。 如果您的存儲不僅僅是緩存,則需要在服務器重新啟動時保持持久性。

第二是代碼重新加載。 Snap的未來版本,從0.3開始(可能在12月初到期)將在開發使用中重新加載動態代碼。 這在開發速度方面是一個巨大的優勢,但它使服務器本地狀態成為一項有趣的心理練習。 如果程序員更改了類型/初始化/服務器本地狀態,則需要重新初始化。 那里有一些巨大的工程挑戰。

當我編寫0.3的動態重載代碼時,我在這個問題上掙扎了一段時間。 然后我看了其他平台。 PHP? 在外部存儲所有內容(數據庫,內存緩存等)。 根本沒有內存中的交叉請求存儲。 Ruby on Rails? 相同。

結合第一期中固有的挑戰,我得出結論,除了可能的緩存優化之外,服務器應該是無狀態的。 保留為其設計的庫/外部進程的持久性問題。

所以我設計了生產和開發加載器使用的通用接口(一個使用靜態加載,另一個使用動態加載)來獲取3個函數:初始化函數,清理函數和使用初始化函數返回的狀態的處理程序。 在生產模式下,編譯為在服務器啟動時調用initialize,在服務器關閉時進行清理。 在開發模式下,它編譯為:對於每個請求,動態加載所有3,然后運行init,handler,cleanup。 顯然,任何國家都不會以這種方式交叉請求。

然后我的答案變成:通過一些具有內置持久性的機制進行交叉請求存儲,並使服務器狀態成為其接口。 如果要在進程內工作,請使用happstack-state或sqlite之類的東西,如果要在本地進程外工作,請使用數據庫或其他外部存儲。

同樣作為補充說明,由於添加了MonadSnap接口,在Snap 0.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。 希望這可以幫助。

我發現了兩個與會話相關的包:

snap-auth由Snap Framework團隊制作,或者至少由其作者/ contirbutor(Ozgun Ataman)制作。 它針對身份驗證和會話管理。 使用ByteString到ByteString的映射完成會話管理,這意味着您只能將已經序列化的數據存儲到ByteString:

type Session = Map ByteString ByteString

另一方面, mysnapsession允許您使用任意類型來建模會話。 但是, Map類型的會話有一些輔助函數。 更多細節在這里 作者Chris Smith也是Snap Framework項目的一部分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM