改札:セッション内でリクエストを同期する方法
-
12-09-2019 - |
質問
シナリオ:Tomcat サーバー上で実行される Apache Wicket ベースの Web アプリケーション。
ユーザーがブラウザで URL を開くと、セッションが作成され、シンプルなメイン ページがブラウザに表示され、ユーザーがボタンをクリックすると、 AJAX 呼び出しが呼び出されます. 。アプリケーションはリクエストを取得し、応答を準備する処理を実行します。同時にユーザーまたはブラウザの JavaScript が呼び出す 別の AJAX 呼び出し -- この 2 番目のリクエストはアプリケーション内の別のスレッドで処理されます。また、アプリケーションのほとんどの部分はセッション固有でスレッドセーフではないため (1 ユーザー = 1 セッションであるため)、 例外がスローされる.
可能な解決策:
すべてのアプリケーションクラスをスレッドセーフにする (非常にコストがかかる)
GUI を調整して、1 つのセッションで 2 つの AJAX 呼び出しを同時に実行しないようにします (ブラウザー GUI の性質上不可能です)
Wicket または Tomcat レベルで 1 つのセッション内のすべてのリクエストを同期します (しかし、どのようにして?)
別の練習やテクニック???
ありがとう
解決
同じのPageMap中内のページまたはコンポーネントへの要求 単一のセッションはすでに同期している - 一度に一つのスレッドだけ。などのリソースに対する要求 画像、JavaScript、CSSファイルなどが非同期で処理されます。 (別のクライアント 各クライアントが独自のセッションとのPageMapを)持っているとして互いをブロックすることはありません。
しかし、セッション自体内の項目へのアクセスが、私は信じて、明示的に同期化されていません。
コンテナは、要求間でセッション/ページで何かをして自由であるように、ところで、リクエストスレッドではないスレッドからセッション/ページにアクセスすると、良いアイデアではありません - 例えばディスクなどにそれを書き出します。
他のヒント
スローされる例外とは何ですか?例外がスローされた場合、私はより多くの注意とそうでないかもしれないセッション全体と同期または処理する必要がSessionオブジェクトのクリティカルセクションがあることが前提となります。
私はあまりそれらを利用する理由はありませんでしたが、私は(org.apache.wicket.ajaxパッケージにあります)改札-ajax.jsの一環として、チャネルがある知っています。これらは、複数のAJAX呼び出しの処理方法を制御します。彼らは一見の価値があるかもしれません。このファイルでは、次のコメントです。
/**
* Channel management
*
* Wicket Ajax requests are organized in channels. A channel maintain the order of
* requests and determines, what should happen when a request is fired while another
* one is being processed. The default behavior (stack) puts the all subsequent requests
* in a queue, while the drop behavior limits queue size to one, so only the most
* recent of subsequent requests is executed.
* The name of channel determines the policy. E.g. channel with name foochannel|s is
* a stack channel, while barchannel|d is a drop channel.
*
* The Channel class is supposed to be used through the ChannelManager.
*/