Your structure is as follows:
ββββββββββββββββββββ β completionFuture | ββββββββββββββββββββ β β ββββββββββββββββ βββββββββββββ β whenComplete | β thenApply | ββββββββββββββββ βββββββββββββ
Therefore, when you cancel the future thenApply , the original completionFuture object remains untouched, since it does not depend on the thenApply stage. If, however, you do not bind the thenApply step, you return the original completionFuture instance, and canceling this step cancels all the dependent steps, as a result of which the whenComplete action should be executed immediately.
But when the thenApply step thenApply canceled, completionFuture can still end when the pollRemoteServer(jobId).equals("COMPLETE") condition is pollRemoteServer(jobId).equals("COMPLETE") , because this poll does not stop. But we do not know the relationship jobId = schedule(something) and pollRemoteServer(jobId) . If your application state changes in such a way that this condition will never be fulfilled after canceling the download, this future will never end ...
As for your last question, in which future βshould I stick?β, There is no need to have a linear chain of futures, while the convenient CompletableFuture methods make it easier to create such a chain, more than often, its least useful thing, since you could just write block of code if you have a linear relationship. Your chain model of two independent steps is correct, but cancellation does not work through it, but it will not work through a linear chain.
If you want to cancel the initial stage, you need a link to it, but if you want to get the result of the dependent stage, you will also need a link to this stage.
source share