Interface Pipeline
-
- All Known Implementing Classes:
DefaultPipeline
,DrasylPipeline
,EmbeddedPipeline
public interface Pipeline
A list ofHandler
s which handles or intercepts inbound events and outbound operations of aDrasylNode
.Pipeline
implements an advanced form of the Intercepting Filter pattern to give a user full control over how an event is handled and how theHandler
s in a pipeline interact with each other. This implementation is very closely based on the netty implementation.Creation of a pipeline
Each per DrasylNode exists one pipeline and it is created automatically when a new node is created.
How an event flows in a pipeline
The following diagram describes how I/O events are processed by
Handler
s in aPipeline
typically. An I/O event is handled by either aInboundHandler
or aOutboundHandler
and be forwarded to its closest handler by calling the event propagation methods defined inHandlerContext
, such asHandlerContext.fireRead(ApplicationMessage)
andHandlerContext.write(ApplicationMessage)
.I/O Request via
HandlerContext
| +---------------------------------------------------+---------------+ | Pipeline | | | \|/ | | +---------------------+ +-----------+----------+ | | | Inbound Handler N | | Outbound Handler 1 | | | +----------+----------+ +-----------+----------+ | | /|\ | | | | \|/ | | +----------+----------+ +-----------+----------+ | | | Inbound Handler N-1 | | Outbound Handler 2 | | | +----------+----------+ +-----------+----------+ | | /|\ . | | . . | | HandlerContext.fireIN_EVT() HandlerContext.OUT_EVT() | | [ method call] [method call] | | . . | | . \|/ | | +----------+----------+ +-----------+----------+ | | | Inbound Handler 2 | | Outbound Handler M-1 | | | +----------+----------+ +-----------+----------+ | | /|\ | | | | \|/ | | +----------+----------+ +-----------+----------+ | | | Inbound Handler 1 | | Outbound Handler M | | | +----------+----------+ +-----------+----------+ | | /|\ | | +---------------+-----------------------------------+---------------+ | \|/ +---------------+-----------------------------------+---------------+ | | | | | [ MessageSink.send() ] [ DrasylNode.send() ] | | | | drasyl Internal I/O | +-------------------------------------------------------------------+An inbound event is handled by the inbound handlers in the bottom-up direction as shown on the left side of the diagram. An inbound handler usually handles the inbound data generated by the I/O thread on the bottom of the diagram. The inbound data is often read from a remote peer via the actual input operation such as
MessageSink.send(RelayableMessage)
. If an inbound event goes beyond the top inbound handler, it is passed to the application.An outbound event is handled by the outbound handler in the top-down direction as shown on the right side of the diagram. An outbound handler usually generates or transforms the outbound traffic such as write requests. If an outbound event goes beyond the bottom outbound handler, it is handled by the
Messenger.send(RelayableMessage)
which performs the actual output operation.For example, let us assume that we created the following pipeline:
Pipeline
p = ...; p.addLast("1", new InboundHandlerA()); p.addLast("2", new InboundHandlerB()); p.addLast("3", new OutboundHandlerA()); p.addLast("4", new OutboundHandlerB()); p.addLast("5", new InboundOutboundHandlerX());Inbound
means it is an inbound handler. The class whose name starts withOutbound
means it is a outbound handler.In the given example configuration, the handler evaluation order is 1, 2, 3, 4, 5 when an event goes inbound. When an event goes outbound, the order is 5, 4, 3, 2, 1. On top of this principle,
Pipeline
skips the evaluation of certain handlers to shorten the stack depth:- 3 and 4 don't implement
InboundHandler
, and therefore the actual evaluation order of an inbound event will be: 1, 2, and 5. - 1 and 2 don't implement
OutboundHandler
, and therefore the actual evaluation order of a outbound event will be: 5, 4, and 3. - If 5 implements both
InboundHandler
andOutboundHandler
, the evaluation order of an inbound and a outbound event could be 125 and 543 respectively.
Forwarding an event to the next handler
As you might noticed in the diagram shows, a handler has to invoke the event propagation methods in
HandlerContext
to forward an event to its next handler. Those methods include:- Inbound event propagation methods:
- Outbound event propagation methods:
Thread safety
A
Handler
can be added or removed at any time because aPipeline
is thread safe.- But for every invocation of:
the invocation is scheduled in theDrasylScheduler
, therefore the order of invocations can't be guaranteed. You have to ensure by yourself, that your handlers are thread-safe if you need it. Also, you have to ensure the order of messages, if you need it.
-
-
Method Summary
All Methods Instance Methods Abstract Methods Modifier and Type Method Description Pipeline
addAfter(String baseName, String name, Handler handler)
Inserts aHandler
after an existing handler of this pipeline.Pipeline
addBefore(String baseName, String name, Handler handler)
Inserts aHandler
before an existing handler of this pipeline.Pipeline
addFirst(String name, Handler handler)
Inserts aHandler
at the first position of this pipeline.Pipeline
addLast(String name, Handler handler)
Appends aHandler
at the last position of this pipeline.HandlerContext
context(String name)
Returns the context object of theHandler
with the specified name in this pipeline.void
executeInbound(Event event)
void
executeInbound(ApplicationMessage msg)
void
executeOutbound(ApplicationMessage msg)
Handler
get(String name)
Returns theHandler
with the specified name in this pipeline.Pipeline
remove(String name)
Removes theHandler
with the specified name from this pipeline.Pipeline
replace(String oldName, String newName, Handler newHandler)
Replaces theHandler
of the specified name with a new handler in this pipeline.
-
-
-
Method Detail
-
addFirst
Pipeline addFirst(String name, Handler handler)
Inserts aHandler
at the first position of this pipeline.- Parameters:
name
- the name of the handler to insert firsthandler
- the handler to insert first- Throws:
IllegalArgumentException
- if there's an entry with the same name already in the pipelineNullPointerException
- if the specified handler isnull
-
addLast
Pipeline addLast(String name, Handler handler)
Appends aHandler
at the last position of this pipeline.- Parameters:
name
- the name of the handler to appendhandler
- the handler to append- Throws:
IllegalArgumentException
- if there's an entry with the same name already in the pipelineNullPointerException
- if the specified handler isnull
-
addBefore
Pipeline addBefore(String baseName, String name, Handler handler)
Inserts aHandler
before an existing handler of this pipeline.- Parameters:
baseName
- the name of the existing handlername
- the name of the handler to insert beforehandler
- the handler to insert before- Throws:
NoSuchElementException
- if there's no such entry with the specifiedbaseName
IllegalArgumentException
- if there's an entry with the same name already in the pipelineNullPointerException
- if the specified baseName or handler isnull
-
addAfter
Pipeline addAfter(String baseName, String name, Handler handler)
Inserts aHandler
after an existing handler of this pipeline.- Parameters:
baseName
- the name of the existing handlername
- the name of the handler to insert afterhandler
- the handler to insert after- Throws:
NoSuchElementException
- if there's no such entry with the specifiedbaseName
IllegalArgumentException
- if there's an entry with the same name already in the pipelineNullPointerException
- if the specified baseName or handler isnull
-
remove
Pipeline remove(String name)
Removes theHandler
with the specified name from this pipeline.- Parameters:
name
- the name under which theHandler
was stored.- Throws:
NoSuchElementException
- if there's no such handler with the specified name in this pipelineNullPointerException
- if the specified name isnull
-
replace
Pipeline replace(String oldName, String newName, Handler newHandler)
Replaces theHandler
of the specified name with a new handler in this pipeline.- Parameters:
oldName
- the name of theHandler
to be replacednewName
- the name under which the replacement should be addednewHandler
- theHandler
which is used as replacement- Throws:
NoSuchElementException
- if the handler with the specified old name does not exist in this pipelineIllegalArgumentException
- if a handler with the specified new name already exists in this pipeline, except for the handler to be replacedNullPointerException
- if the specified old handler or new handler isnull
-
get
Handler get(String name)
Returns theHandler
with the specified name in this pipeline.- Returns:
- the handler with the specified name.
null
if there's no such handler in this pipeline.
-
context
HandlerContext context(String name)
Returns the context object of theHandler
with the specified name in this pipeline.- Returns:
- the context object of the handler with the specified name.
null
if there's no such handler in this pipeline.
-
executeInbound
void executeInbound(ApplicationMessage msg)
-
executeInbound
void executeInbound(Event event)
-
executeOutbound
void executeOutbound(ApplicationMessage msg)
-
-