トレードのリストに対するJMSフェッチリクエストをJMSキューに配置するStruts2アクションクラスがあります。このJMSフェッチメッセージは外部プロセスによって処理され、外部タスク処理アプリによって処理されるTradeファイルの数に応じて、数秒または数分かかる場合があります。
このHTTPリクエストを適切な応答で処理する方法を知りたいです。クライアントはトレードのリストが返されるまで待ちますか?(クライアント(UI)はそれに対応する必要があり、その間は他に何もする必要はありません)。
私がそれにアプローチした方法は、HTTPリクエスト->Struts2アクション->です。
- Runnableを呼び出して、別のスレッド(Actionクラスとは別)で実行します
- UIは待機します
- アクションクラスのスレッドは、実行可能になるまでスリープします。
- タスクが完了したら、トレードのリストをUIに戻します
フローは次のとおりです。
- JMSフェッチ要求をQueue1に配置します
RunnableのExecutorService
CClass cclass = new CClass(); final ExecutorService execSvc = Executors.newFixedThreadPool(1); execSvc.execute(cclass);
CClassがトレードのリストを返すrunnableを実装する場合:
List<Trade> tradesList = new ArrayList<Trade>();
@Override
public void run() {
while (true) {
try {
Message message = msgConsumer.receive(); // SYNCHRONOUS / NO MDB
if (message == null){
break;
}
if (message instanceof TextMessage) {
TextMessage txtMessage = (TextMessage) message;
Trade trade = TradeBuilder.buildTradeFromInputXML(txtMessage);
if (trade != null) {
tradesList.add(trade); // tradeList is a CClass class variable
}
}
} catch (JMSException e) {
logger.error("JMSException occurred ", e);
}
}
closeConnection();
}
そして、このランナブルが実行されている間、私はActionクラスでThread.sleepを実行します(ランナブルを別のスレッドで実行させるため)
// In Action class
try {
Thread.sleep(5000); // some time till when the runnable will get executed
} catch (InterruptedException e) {
e.printStackTrace();
}
execSvc.shutdown();
問題は、FutureTaskでCallableを使用してget()を実行すると、結果が返されるまでブロックされます。Runnableを実行する場合、runnableが実行され、tradeListが使用可能になるまで、ActionクラスThreadをスリープ状態にする必要があります。
Runnableアプローチを使用すると、数百のレコードをUIに戻すことができ、メインのActionクラスで5秒のThread.sleep()を提供しますが、数千のレコードをフェッチしてUIに表示する場合は、部分的にのみTradeListを作成します。
これは明らかに失敗のないアプローチではありません。
提案するためのより良いアプローチはありますか?1つの完全な要求(応答フロー)で処理するための手順を説明してください。