2

編集

この質問はこれまでに数回繰り返されてきたので、改訂を自由に調べて、歴史や試みられた事柄に関する背景情報を確認してください。


CompletionServiceをExecutorServiceおよびCallableと一緒に使用して、CXFで生成されたコードを介していくつかの異なるWebサービス上の多数の関数を同時に呼び出しています。これらのサービスはすべて、使用している単一の情報セットに対して異なる情報を提供します。私のプロジェクト。ただし、サービスは例外をスローせずに長期間応答できない可能性があり、情報の組み合わせセットの待機が長くなります。

これに対抗するために、私はすべてのサービスコールを同時に実行しています。数分後、まだ終了していないコールをすべて終了し、できれば、呼び出し可能ファイル内から、またはスローすることによって、まだ実行されていないコールをログに記録します。詳細な例外。

これは、私がすでに行っていることを説明するための非常に単純化されたコードです。

private Callable<List<Feature>> getXXXFeatures(final WiwsPortType port, 
final String accessionCode) {
    return new Callable<List<Feature>>() {
        @Override
        public List<Feature> call() throws Exception {
            List<Feature> features = new ArrayList<Feature>();
            //getXXXFeatures are methods of the WS Proxy
            //that can take anywhere from second to never to return
            for (RawFeature raw : port.getXXXFeatures(accessionCode)) {
                Feature ft = convertFeature(raw);
                features.add(ft);
            }
            if (Thread.currentThread().isInterrupted())
                log.error("XXX was interrupted");
            return features;
        }
    };
}

また、WS呼び出しを同時に開始するコードは次のとおりです。

WiwsPortType port = new Wiws().getWiws();
List<Future<List<Feature>>> ftList = new ArrayList<Future<List<Feature>>>();
//Counting wrapper around CompletionService, 
    //so I could implement ccs.hasRemaining()
CountingCompletionService<List<Feature>> ccs = 
        new CountingCompletionService<List<Feature>>(threadpool);
ftList.add(ccs.submit(getXXXFeatures(port, accessionCode)));
ftList.add(ccs.submit(getYYYFeatures(port accessionCode)));
ftList.add(ccs.submit(getZZZFeatures(port, accessionCode)));

List<Feature> allFeatures = new ArrayList<Feature>();
while (ccs.hasRemaining()) {
            //Low for testing, eventually a little more lenient
    Future<List<Feature>> polled = ccs.poll(5, TimeUnit.SECONDS);
    if (polled != null)
        allFeatures.addAll(polled.get());
    else {
        //Still jobs remaining, but unresponsive: Cancel them all
        int jobsCanceled = 0;
        for (Future<List<Feature>> job : ftList)
            if (job.cancel(true))
                jobsCanceled++;
        log.error("Canceled {} feature jobs because they took too long",
                        jobsCanceled);
        break;
    }
}

このコードで私が抱えている問題は、port.getXXXFeatures(...)が戻るのを待っているときに、Callablesが実際にはキャンセルされないが、どういうわけか実行を続けることです。ステートメントからわかるように、port.getFeaturesが戻った後if (Thread.currentThread().isInterrupted()) log.error("XXX was interrupted");に中断フラグが設定されます。これは、キャンセルを呼び出したときに中断されたのではなく、Webサービス呼び出しが正常に完了した後にのみ使用できます。

誰かが私が間違っていることと、一定期間後に実行中のCXF Webサービス呼び出しを停止し、この情報をアプリケーションに登録する方法を教えてもらえますか?

よろしく、ティム

4

2 に答える 2

2

編集 3新しい回答。

次のオプションが表示されます。

  • 問題を機能リクエストとして Apache CXF に投稿してください
  • ACXF を自分で修正し、いくつかの機能を公開します。
  • Apache CXF 内で非同期 WS 呼び出しをサポートするオプションを探す
  • 別の WS プロバイダー (JAX-WS?) への切り替えを検討してください。
  • サービスが RESTful API をサポートしている場合、WS は RESTful API を使用して自分自身を呼び出しますか (例: パラメーター付きの単純な HTTP 要求)
  • 超専門家のみ: 真のスレッド/スレッド グループを使用し、型破りな方法でスレッドを強制終了してください。
于 2009-07-13T17:20:40.360 に答える
1

CXF ドキュメントには、HTTPURLConnection で読み取りタイムアウトを設定するための手順がいくつかあり ます。

それはおそらくあなたのニーズを満たすでしょう。サーバーが時間内に応答しない場合、例外が発生し、callable で例外が発生します。(ただし、代わりにハングする可能性があるバグがあります。それが 2.2.2 で修正されたのか、それとも現在スナップショットにあるだけなのかは思い出せません。)

于 2009-07-15T03:32:25.210 に答える