Background: Flow Event Processing
Flow Constraints
A flow is a
- single-threaded
- lock free
- event driven
- non-blocking
- transactional
piece of code.
Single-threaded means it is always processed by a single thread. No concurrency takes place within a flow.
Lock free means there are no locks required inside a flow, because there is no concurrency.
Event driven means that all invocations of any part of a flow is initiated by an event.
Non-blocking means that components of a flow never block or at least should avoid to block because it blocks the thread which might be needed for other flows.
Transactional means that any persistent changes (persistent memories) that are performed within the processing of a single event is covered by a single transaction. If a flow fails during processing, the transaction is automatically rolled back and messages are redelivered. Transactions only cover SwiftMQ internal queues but not database operations.
Event Types
Event types are:
- message event
- timer event
- callback events
Message events are generated by all Input
components (Queue Input,
Topic Input
and so on) as well as from Flow Start
and Flow Stop
components.
Timer events are generated from all Timer components (Interval Timer
, Next Timer
and so on).
Callback events are generated from all components that initiate a call to an external library, service and enqueue the result of that call as a callback into the event queue.
Flow Event Queue
All flow components that produce events enqueue the events into the event queue of the flow. The events are processed in FIFO manner, one by one from a single thread which is obtained from an associated thread pool from which all flows are served.
When the flow is invoked with that event, the event pops out at the output connector of the component that has enqueued the event. For example, a message event pops out as message at the Input
component that listens on a queue, a timer event pops out at the respective Timer
component.
Event Roots and References
Definition: An event root is the output connector where the event initially starts.
Common event roots are: All Input,
all Timer
components, Flow Start/Stop
components and the Shell Executor
. Further all components that call asynchronous APIs and register event callbacks like the REST Client
components.
Since an event defines a single run through a flow, references on components (like Message Ref
) between different event roots are generally not possible. The only exceptions are Memory
and Flag
components.