Class IteratingCallback

  • All Implemented Interfaces:
    Callback, Invocable
    Direct Known Subclasses:
    AsyncMiddleManServlet.ProxyReader, AsyncProxyServlet.StreamReader, FrameFlusher, HTTP2Flusher, IteratingNestedCallback

    public abstract class IteratingCallback
    extends java.lang.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.

    • Constructor Detail

      • IteratingCallback

        protected IteratingCallback()
      • IteratingCallback

        protected IteratingCallback​(boolean needReset)
    • Method Detail

      • onCompleteSuccess

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

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

        public void iterate()
        This method must be invoked by applications to start the processing of asynchronous sub-tasks.

        It can be called at any time by any thread, and its 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, but in either case by one thread only.

      • succeeded

        public void succeeded()
        Method to invoke when the asynchronous sub-task succeeds.

        Subclasses that override this method must always remember to call super.succeeded().

        Specified by:
        succeeded in interface Callback
        See Also:
        Callback.failed(Throwable)
      • failed

        public void failed​(java.lang.Throwable x)
        Method to invoke when the asynchronous sub-task fails, or to fail the overall asynchronous task and therefore terminate the iteration.

        Subclasses that override this method must always remember to call super.failed(Throwable).

        Eventually, onCompleteFailure(Throwable) is called, either by the caller thread or by the processing thread.

        Specified by:
        failed in interface Callback
        Parameters:
        x - the reason for the operation failure
        See Also:
        isFailed()
      • isClosed

        public boolean isClosed()
        Returns:
        whether this callback has been closed
      • isFailed

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

        public boolean isSucceeded()
        Returns:
        whether this callback and the overall asynchronous task has been succeeded
        See Also:
        onCompleteSuccess()
      • reset

        public boolean reset()
        Resets this callback.

        A callback can only be reset to the idle state from the succeeded or failed states or if it is already idle.

        Returns:
        true if the reset was successful
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object