Registers handler that is synchronously invoked once on completion of this job. When the job is already complete, then the handler is immediately invoked with the job's exception or cancellation cause or null. Otherwise, the handler will be invoked once when this job is complete.

The meaning of cause that is passed to the handler:

  • Cause is null when the job has completed normally.

  • Cause is an instance of CancellationException when the job was cancelled normally. It should not be treated as an error. In particular, it should not be reported to error logs.

  • Otherwise, the job had failed.

The resulting DisposableHandle can be used to dispose the registration of this handler and release its memory if its invocation is no longer needed. There is no need to dispose the handler after completion of this job. The references to all the handlers are released when this job completes.

Installed handler should not throw any exceptions. If it does, they will get caught, wrapped into CompletionHandlerException, and rethrown, potentially causing crash of unrelated code.

Note: Implementation of CompletionHandler must be fast, non-blocking, and thread-safe. This handler can be invoked concurrently with the surrounding code. There is no guarantee on the execution context in which the handler is invoked.