2016-07-26 21 views
3

Nashornをサーブレット内で使用したいと考えています。アイデアは、すべてのリクエストで再利用されるScriptEngineのシングルトンインスタンスを使用することです。リクエストごとに新しいEngineScope Bindingが作成され、そのバインディングでevalが実行されます。次にバインディングがクリアされます。バインディングには共有オブジェクトは渡されません(サーブレットの要求/応答オブジェクトのみ)。Nashorn:シングルトンScriptEngineとの同時評価?スレッドセーフ?

サーブレット内では、ScriptEngineのシングルトンインスタンスが異なるスレッドで同時に評価される可能性があります。正しく動作するのでしょうか、それともスレッドの問題に遭遇しますか?

ScriptEngine engine = getNashornSingleton(); 

ScriptContext newContext = new SimpleScriptContext(); 
newContext.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE); 
Bindings engineScope =newContext.getBindings(ScriptContext.ENGINE_SCOPE); 

engineScope.put("request", request); 
engineScope.put("response", response); 

engine.eval(jsCode, engineScope); 
engineScope.clear(); 

答えて

3

私は上記のようにシングルトンを使用しません。潜在的なスレッドの問題にもかかわらず、(スクリプトの再コンパイルが必要な場合があるため)各要求でバインディングを破棄したくない可能性があります。私たちがやり遂げたのは、エンジンプールとそれに関連するスコープバインドを作成することでした。エンジン/バインディングペア。

各サーブレットリクエストで、プールからエンジン/バインディングのペアを取得し、リクエスト/レスポンスをバインディングに入れてからスクリプトを実行します。特定のエンジン/バインディングペアは、一度に1つのスレッドでのみ実行されるため、心配するスレッドの問題はありません。リクエストが完了すると、エンジン/バインディング・ペアがプールに戻されます。うまくいくと思う。

+0

セットアップに関する詳細を少し詳しく説明できますか? Webapp(Reactを使用したサーバーサイドレンダリング)ではNashornと同様の並行性の問題がありました。 ThreadLocalでエンジンをラップしようとしましたが、パフォーマンスは非常に悪いです。現在、CompiledScriptとInvocableを試しています。 プールはどのくらいですか?スレッドプールサイズに等しい要求がない場合は、問題が発生します。 – mryan

+0

ナッシュエンジンのプールを選択しました。私の最初の試みは、エンジンのプールを持ち、毎回新しいバインドを再作成することでした(しかし、これはスクリプトが呼び出されるたびにナショーンスクリプトを強制的に再コンパイルするように思えたので、サーブレットが同じスクリプトを呼び出すたびにスクリプトを再コンパイルする必要はありませんサーブレットが終了すると、ラッパーオブジェクトがプールに返されます – adamM

+0

リーパースレッドは頻繁に呼び出されます通常のサーブレットよりもやや遅いですが、良いですが、再コンパイルせずにファイルからスクリプトをロードする方法についてはほとんど詳細がありません。オープンソースについて考えていますあなたはどう思いますか? – adamM

関連する問題