サーバー側のセッションは[まだ]SnapFrameworkの一部ではありません。ある種のサーバー側の状態を追加する方法はありますか?
HTTPリクエストごとにカウンターをインクリメントしたいとしましょう。どうすればいいですか?
サーバー側のセッションは[まだ]SnapFrameworkの一部ではありません。ある種のサーバー側の状態を追加する方法はありますか?
HTTPリクエストごとにカウンターをインクリメントしたいとしましょう。どうすればいいですか?
上記の答えは、それに関する限り正しいですが、いくつかの実際の問題を扱っていません。
まず、サーバーの再起動です。ストレージがキャッシュ以上のものである場合は、サーバーの再起動後も耐久性がある必要があります。
2番目はコードのリロードです。0.3以降のSnapの将来のバージョン(おそらく12月初旬にリリース予定)では、開発用に動的なコードがリロードされます。これは開発速度の点で大きな利点ですが、サーバーローカル状態を興味深いメンタルエクササイズにします。プログラマーがサーバーローカル状態のタイプ/初期化/その他を変更した場合は、再初期化する必要があります。そこにはいくつかの途方もないエンジニアリング上の課題があります。
0.3の動的リロードコードを書いていたとき、しばらくの間その問題に苦労しました。次に、他のプラットフォームを調べました。PHP?すべてを外部に保存します(データベース、memcacheなど)。メモリ内のクロスリクエストストレージはまったくありません。Ruby on Rails?同じ。
最初の問題に固有の課題と組み合わせると、キャッシュの最適化の可能性を除けば、サーバーはステートレスである必要があるという結論に達しました。そのために設計されたライブラリ/外部プロセスに耐久性の懸念を残します。
そこで、本番ローダーと開発ローダー(1つは静的読み込み、もう1つは動的読み込み)で使用される共通のインターフェイスを設計して、初期化関数、クリーンアップ関数、初期化関数によって返される状態を使用するハンドラーの3つの関数を使用しました。本番モードでは、サーバーの起動時に初期化を呼び出し、サーバーのシャットダウン時にクリーンアップを呼び出すようにコンパイルされます。開発モードでは、次のようにコンパイルされます。リクエストごとに、3つすべてを動的にロードしてから、init、handler、cleanupを実行します。明らかに、そのようにクロスリクエストを生き残る州はありません。
そして、私の答えは次のようになります。組み込みの耐久性を備えたメカニズムを介してクロスリクエストストレージを実行し、サーバーの状態をそのインターフェイスにします。インプロセスで作業する場合はhappstack-stateやsqliteなどを使用し、ローカルプロセスの外部で作業する場合はデータベースやその他の外部ストアを使用します。
追記として、接続プールなどの「グローバル」リソースの管理も、MonadSnapインターフェイスが追加されているため、Snap0.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つのセッション関連パッケージが見つかりました。
snap-authは、Snap Frameworkチーム、または少なくともその作成者/寄稿者の1人(Ozgun Ataman)によって作成されます。認証とセッション管理を対象としています。セッション管理は、ByteStringからByteStringへのマップを使用して実行されます。これは、すでにByteStringにシリアル化されているデータのみを格納できることを意味します。
type Session = Map ByteString ByteString
一方、mysnapsessionでは、任意のタイプを使用してセッションをモデル化できます。Map
ただし、このタイプのセッションにはいくつかのヘルパー関数があります。詳細はこちら。著者のChrisSmithも、SnapFrameworkプロジェクトの一部です。