Class IteratingCallback

All Implemented Interfaces:
Callback, Invocable
Direct Known Subclasses:
AsyncMiddleManServlet.ProxyReader, AsyncProxyServlet.StreamReader, ControlFlusher, DemandingFlusher, FrameFlusher, HTTP2Flusher, InstructionFlusher, IteratingNestedCallback, MessageFlusher

public abstract class IteratingCallback extends Object implements Callback
This specialized callback implements a pattern that allows a large job to be broken into smaller 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 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 uses an AtomicReference to record whether success callback has been called during the processing of a sub task, and if so then the processing iterates rather than recurring.

Subclasses must implement method process() where the sub task is executed and a suitable IteratingCallback.Action is returned to this callback to indicate the overall progress of the job. This callback is passed to the asynchronous execution of each sub task and a call the succeeded() on this callback represents the completion of the sub task.

  • Constructor Details

    • IteratingCallback

      protected IteratingCallback()
    • IteratingCallback

      protected IteratingCallback(boolean needReset)
  • Method Details

    • process

      protected abstract IteratingCallback.Action process() throws Throwable
      Method called by iterate() to process the sub task.

      Implementations must start the asynchronous execution of the sub task (if any) and return an appropriate action:

      the appropriate Action
      Throwable - if the sub task processing throws
    • onCompleteSuccess

      protected void onCompleteSuccess()
      Invoked when the overall task has completed successfully.
      See Also:
    • onCompleteFailure

      protected void onCompleteFailure(Throwable cause)
      Invoked when the overall task has completed with a failure.
      cause - the throwable to indicate cause of failure
      See Also:
    • iterate

      public void iterate()
      This method must be invoked by applications to start the processing of sub tasks. It can be called at any time by any thread, and it's contract is that when called, then the process() method will be called during or soon after, either by the calling thread or by another thread.
    • succeeded

      public void succeeded()
      Invoked when the sub task succeeds. Subclasses that override this method must always remember to call super.succeeded().
      Specified by:
      succeeded in interface Callback
      See Also:
    • failed

      public void failed(Throwable x)
      Invoked when the sub task fails. Subclasses that override this method must always remember to call super.failed(Throwable).
      Specified by:
      failed in interface Callback
      x - the reason for the operation failure
    • close

      public void close()
    • isClosed

      public boolean isClosed()
    • isFailed

      public boolean isFailed()
      whether this callback has failed
    • isSucceeded

      public boolean isSucceeded()
      whether this callback has succeeded
    • reset

      public boolean reset()
      Resets this callback.

      A callback can only be reset to IDLE from the SUCCEEDED or FAILED states or if it is already IDLE.

      true if the reset was successful
    • toString

      public String toString()
      toString in class Object