2011-08-16 19 views
2

私はPlay! ScriptEngineを含むjavax.scriptパッケージを大量に使用するフレームワーク。 ScriptEngineは作成するのに費用がかかり、複数のリクエストでそれらを使用するのが理にかなっています(複数のScriptEngineを作成するのは面倒ですが、少なくとも1つのリクエストごとにScriptEnginesを作成しません)。再生!フレームワーク:複数のリクエストに対するインスタンスの再利用

私はこのケースがScriptEnginesに制限されていないと思うので、私はそのようなケースを処理するために気づいていないフレームワークに何かがあるかもしれません。

ありがとうございました! Malax

+0

1つの静的インスタンスでは不十分ですか? Playフレームワークは、JEEコンポーネントモデルの反論であり、主に要求間でステートレスになります。 – Jeremy

+0

これは私の最初のショットで、1つのスクリプトエンジンの静的インスタンスを持っていました。この問題は、ScriptEnginesがスレッド保存ではなく、要求がスレッドプールによってディスパッチされ(静的フィールドがスレッド間で共有されるため)、エンジンが異なるスレッドによって同時に使用される可能性があることです。 – Malax

答えて

2

再生はステートレスなので、オブジェクトをユーザーにリンクする「セッションのような」メカニズムはありません。 2つの選択肢があります:

キャッシュを使用します。一意のIDを持つキャッシュにScriptEngineを格納し、それがまだ存在するかどうかを確認するメソッドを追加します。何かのように:

また、ScriptEngineの静的インスタンスを含むシングルトンオブジェクトを作成するか、サーバーが起動すると常にそこに存在します。

私はキャッシュのほうが最良のアプローチだと言います。

EDIT:あなたのコメントに、これは状況に依存します:あなたはユニークユーザーの複数のリクエスト間でエンジンを再利用したい場合は

  1. (つまり、各ユーザーはで動作するように彼自身のScriptEngineのを持っています)キャッシュメソッドは、キャッシュがエンジンをユーザーIDにリンクするときに機能します。これはスレッド化の問題も解決します。
  2. それ以外の場合は、複数のユーザーからの複数の要求で再利用する場合は、静的メソッドを使用する方が良い方法です。しかし、あなたが言及したように、アクセスはスレッドセーフではなく、Playまたは任意のシステムで行われます。

私はあなたの最善の策は、それらと非同期で作業することだと考えています。私はあなたがScriptEnginesを使用する方法を知っているが、このような何かしようとしないでください。ご要望に応じて

  • を、同じ要求ではScriptEngineの処理要求
  • マーキングDBからテーブルにエントリを格納しますasynchronousジョブを起動します(または30秒ごとに実行する)。
  • ジョブは、テーブルの最初のエントリを読み取り、削除し、タスクを実行し、ユーザーに応答を返します。ジョブには、動作するScriptEngineのプールがあります。
  • 現在のジョブが動作している間にジョブが再度起動されないため、十分な要求があれば、ジョブは決して動作を停止しません。もしそうなら、それはあなたがその時にエンジンを必要としないことを意味し、彼らは要求に応じて再作成されます。

この方法で、スレッドとの問題を無視して、プールと線形に作業します。これを行うことができない場合は、複数のスレッドを生成するサーバー環境でスレッドセーフではないオブジェクトを共有しようとすることができないため、ScriptEngineのスレッドセーフティを修正する必要があります。

+0

静的インスタンスについて - 主な質問に関する私のコメントを参照してください。この問題はキャッシュソリューションでも発生しているようです。 :(プールを使用する場合は – Malax

+0

+1。 – Jeremy

0

なぜScript-Poolを実装しないのですか?したがって、各リクエストは、JDBC接続プールと同じ方法でプールからインスタンスを取得します。 しかし、Script-Engineがステートレスであることを確認してください。

関連する問題