The Processing Pattern
This is an example implementation of a Processing pattern, a generalized approach for submitting and asynchronously processing (ie: executing) "work" in a system.
The Processing Pattern advocates that;
- ProcessingSessions are used to submit "work" (typically regular objects) for asynchronous processing.
- A Submission Outcome must be returned after each submission to track the progress of said Submission.
- A Processing Pattern client will only have to concern itself with the above two concepts.
- Dispatchers are responsible for routing Submissions for processing.
- A TaskDispatcher will dispatch special "work" which implements the Task interface.
- A Task that implements ResumableTask interface can checkpoint state (checkpoint as in saving intermediate state which can be retrieved when resuming), yield execution and resume.
- An Executor will execute Tasks.
This implementation of the Processing Pattern additionally advocates that;
- Many Dispatchers may be "registered" to enable specific processing of different types of Submission.
- Dispatchers are consulted in order of "registration" for each Submission to determine suitability for routing. (This is called "dispatch chaining").
- Out of the box, three Dispatcher implementations are provided, one to Log the submissions, one to execute Java Runnables or Java Callables, and one (the DefaultTaskDispatcher) that dispatches Tasks to Executor implementations.
- The Executors need to register themselves with the Framework.
- Out of the box, two Executor implementations are provided, GridExecutor which execute Tasks anywhere in the grid, the QueueBasedExecutor instead queues the Tasks and lets a QueuePollExecutor poll for Tasks to execute.
- Tasks are mapped to Executors using string based pattern matching.
Rationale
This implementation of the Processing Pattern provides a simple and powerful extensible framework for the processing of "work" across a Coherence Cluster. Work can be submitted without needing to know the internals of Coherence or building custom configurations. Unlike the traditional hub-and-spoke / master-worker / broker-agent, the Processing Pattern implementation avoids the classic "single-point-of-failure", "single-point-of-dispatch", "single-point-of-contention" problems as the core state management and distribution is managed by the Data Grid.
Additionally, it provides runtime support to ResumableTasks to enable checkpointing of long running work and a suspend/resume model enabling long running tasks.
Further it supports execution of work based on a run anywhere in the grid paradigm, as well as a more controlled execution model where work is polled by specific QueuePollExecutors executing on specific nodes in the grid.
Basic design
Dispatchers and Submissions
- In order to process work, one or more Dispatchers need to be registered.
- When a dispatcher is registered, each Submission will be handed to each Dispatcher in registration order until
one dispatcher accepts the Submission.
- When a dispatcher has accepted the Submission a SubmissionOutcome is returned to the client.
- When the dispatcher, (or in the case of Task dispatching, the Executor), has processed the Submission the SubmissionOutcome is signaled and the result is available to the client.
The following diagram illustrates the main structure of the design of the Processing Pattern.

Task dispatching and execution of ResumableTasks
- ResumableTasks are handled by a TaskDispatcher that hooks in to the Dispatcher chains handling Submissions with a ResumableTask in them.
- An Executor executes the ResumableTask.
- Tasks are matched against Executors by string matching - Task.getType matches Executor.getTaskType.
- Two executor types are available out of the box, a GridExecutor that executes a Task anywhere in the grid and QueueBasedExecutor which queues Tasks for a specific QueuePollExecutor. The QueuePollExecutor can be used to execute Tasks on specific nodes in the grid.
- When a ResumableTask executes, a TaskExecutionEnvironment is available to support checkpointing, progress reporting and determination of resumption.
- A resumable task can return a special Yield object to suspend execution.
The following diagram illustrates the structure of the Task Execution.

The following diagram illustrates the states a ResumableTask can be in.

What's New
The following changes have been made since the Processing Pattern 1.0.0 release.
- Changed terminology from 1.0; Submitter now called ProcessingSession.
- Introduced timing details on SubmissionOutcome, retrieve how long time it took to process.
- Introduced SubmissionOutcomeListener to enable notifications on the progress of a Submission.
- Introduce Task, ResumableTask, Executor interfaces to support Task Execution.
- TaskDispatcher, plugging in to the Dispatcher framework to support Task Execution.
- Framework improvements to abstract away the implementation details for an Executor/Dispatcher.
In-depth example
For a more in-depth example of the Processing Pattern, please go to the Processing Pattern Examples.
|
Outline
Dependencies
This project (like other Coherence Incubator projects) uses Apache Ivy for dependency specification and management. While a standard ivy.xml definition file ships with the source and documentation distribution, the following diagram visually indicates the current dependencies.
|