A pipeline component can be considered a composite java.lang.Runnable
implementation. It delegates the invocation of it's run() to a number of
dependant components called Valves.
Pipeline component also provides support for error handling and state cleanup, modelled
after Java try-catch-finally statement. Three sets of Valves are defined for a
pipeline: try Valves that perform the processing, catch Valves that are
invoked only if an unhandled exception occurs in one of the try Valves (all
subsequent try Valves are not invoked in such situation). In case of a "double
fault" - an unhandled exception in one of the catch Valves, the remaining
catch Valves are not invoked. All of the finally Valves
are always invoked, even if some of them throw exceptions.
A pipeline usually introduces a notion of "unit of work" that is passed between the Valves. Unfortunately it's impossible to define in a type-safe way without generic types, and there are multiple possible variants of Valve relationships. We decided to refrain from making these policy decisions, except that we endorse communication of the Valves through the thread Context.
| position | type | descritpion |
|---|---|---|
| 1 | org.objectledge.context.Context |
the thread's context |
| 2 | import org.jcontainer.dna.Logger |
the logger |
| 3 | java.lang.Runnable[] |
the valves to invoke in the try section |
| 4 | java.lang.Runnable[] |
the valves to invoke in the catch section |
| 5 | java.lang.Runnable[] |
the valves to invoke in the finally section |