0

CompletionStage.whenComplete() executes an action after the current stage completes, but what happens if the stage has dependent stages? Is there a way to execute an action after all dependent stages have completed when I don't have access to the dependencies?

Example:

CompletionStage<Void> parent = ...;
registerCleanup(parent);
CompletionStage<Void> child = parent.thenApply(expensiveOperation);

registerCleanup() only gets access to the parent, but it wishes to register an action that will clean up after child executes. Can this be done?

Didier L
  • 18,905
  • 10
  • 61
  • 103
Gili
  • 86,244
  • 97
  • 390
  • 689

1 Answers1

0

This is not possible in general, at least with the CompletionStage or CompletableFuture API's.

If you consider it, this would require to know

  • when all dependencies have been executed
  • but moreover, whether any new dependencies will be added in the future

When you look at your code sample, how could registerCleanup() know that you will add a thenApply() dependency on the next line? How could it know that you won't add another dependency in 2 hours?

The only way to know this would be to track the latest moment before the initial CompletionStage and all its dependencies are about to be garbage collected, after which it wouldn't be possible to add more dependencies.

This could maybe be implemented by relying on PhantomReferences or Java 9's new Cleaner API but you should probably not do it on the CompletionStage itself, but on the result that it produced – which is, I suppose, what you really want to clean.

Indeed someone could have saved a reference to that result somewhere else, such that even after all dependent stages have executed, you still don't know whether you can perform your cleanup.

Note that it might be simpler however to just document your API such that users take care of the cleanup.

Didier L
  • 18,905
  • 10
  • 61
  • 103