私はいくつかのリソースを "閉じる"より良い方法を探しています、ここでは外部Process
を破棄し、CompletableFuture
のチェーンにあります。今私のコードは、おおよそ次のようになります。私は見CompletableFutureチェーンの外部プロセスを閉じる
public CompletableFuture<ExecutionContext> createFuture()
{
final Process[] processHolder = new Process[1];
return CompletableFuture.supplyAsync(
() -> {
try {
processHolder[0] = new ProcessBuilder(COMMAND)
.redirectErrorStream(true)
.start();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
return PARSER.parse(processHolder[0].getInputStream());
}, SCHEDULER)
.applyToEither(createTimeoutFuture(DURATION), Function.identity())
.exceptionally(throwable -> {
processHolder[0].destroyForcibly();
if (throwable instanceof TimeoutException) {
throw new DatasourceTimeoutException(throwable);
}
Throwables.propagateIfInstanceOf(throwable, DatasourceException.class);
throw new DatasourceException(throwable);
});
}
問題は、それがエラーの場合に閉鎖することができるように、プロセスへの参照を保持している「ハック」1要素の配列です。いくつかの "コンテキスト"をexceptionally
(またはそれを達成するための他の方法)に渡すことを可能にするいくつかのCompletableFuture
APIがありますか?
私はカスタムCompletionStage
の実装を考えていましたが、 "ホルダー"変数を取り除くのは大きな仕事のようです。
'.waitFor'ブロックと私はおそらく非常に大きな' InputStream'を消費したいので、私は使うことができません。(したがって、 '.redirectErrorStream(true)'、後で "エラー検出"があります。 2番目の方法はちょっと複雑です( 'CompletableFuture'を含む3つの先物)、私は試してみましょう。 –
Xaerxess
*非同期*動作でブロックします。それは 'thenAcceptAsync'やよく' CompleteableFuture'の一般的な段階です。独立したステージを同時に実行できます。ここで、 'PARSER.parse'と' process.waitFor'は同時に独立した段階で実行されます。 – Holger
ああ、そうだ。 waitForを試してみましょう! – Xaerxess