Class IteratingCallback

java.lang.Object
org.eclipse.jetty.util.IteratingCallback
All Implemented Interfaces:
Callback, Invocable
Direct Known Subclasses:
AsyncMiddleManServlet.ProxyReader, AsyncProxyServlet.StreamReader, DemandingFlusher, FrameFlusher, HTTP2Flusher, IteratingNestedCallback

public abstract class IteratingCallback extends Object implements Callback
This specialized callback implements a pattern that allows a large asynchronous task to be broken into smaller asynchronous sub-tasks using iteration rather than recursion.

A typical example is the write of a large content to a socket, divided in chunks. Chunk C1 is written by thread T1, which also invokes the callback, which writes chunk C2, which invokes the callback again, which writes chunk C3, and so forth.

The problem with the example above is that if the callback thread is the same that performs the I/O operation, then the process is recursive and may result in a stack overflow. To avoid the stack overflow, a thread dispatch must be performed, causing context switching and cache misses, affecting performance.

To avoid this issue, this callback atomically records whether the callback for an asynchronous sub-task has been called during the processing of the asynchronous sub-task, and if so then the processing of the large asynchronous task iterates rather than recursing.

Subclasses must implement method process() where the asynchronous sub-task is initiated and a suitable IteratingCallback.Action is returned to this callback to indicate the overall progress of the large asynchronous task. This callback is passed to the asynchronous sub-task, and a call to succeeded() on this callback represents the successful completion of the asynchronous sub-task, while a call to failed(Throwable) on this callback represents the completion with a failure of the large asynchronous task.