-
Notifications
You must be signed in to change notification settings - Fork 892
Design Types and Patterns
Throughout Aeron there are a number of common types and approaches that are reused in a number of different scenarios. Generally a naming convention is used to highlight this common behaviour. This page will attempt to outline some of those concepts, describe the common behaviour and point out some example use cases.
The purpose of an adapter is to handle incoming messages in their raw binary form and coerce them to application type or types for use elsewhere in the system. A common response to this "oh, this is where serialisation occurs". However, this is not quite correct as in a number of places Aeron doesn't do serialisation, instead it does flyweight based decoding, so much of the serialisation happens lazily. In these cases the Adapter will be doing a partial decode in order to determine the appropriate flyweight to apply to the incoming message.
Some examples of Adapters in Aeron include:
- ClientCommandAdapter
- ConsensusAdapter
- DriverEventAdapter
- and many more...
Taking the ConsensusAdapter
class for example.
Most of its fields that are instances of SBE Decoders.
It contains an onFragment
callback that matches the FragmentHandler
FunctionalInterface, for use in handling messages received via an Aeron Subscription or Image poll call.
Within the callback it initially decodes the header of the incoming message, which contains a templateId
that identifies the specific decoder to apply to the incoming message.
The DriverEventAdapter
and ClientCommandAdapter
are similar, but contain some small differences.
Instead of using SBE decoders, they are using hand written flyweights (the internals of Aeron messaging use these instead of SBE encoders/decoders) and the callback pattern is different as it includes an additional type parameter on the callback.
These adapters are being used with the ring buffer that passes messages between the Aeron client and the Media Driver, but the concept is still the same.
Both have a switch statement that checks the type of the message and uses that to identify the appropriate flyweight for further processing.
Proxies are the inverse of the Adapters. They take a request containing application specific types and coerce them into raw byte arrays for transmission over some media.
Examples include:
The ArchiveProxy
and ConsensusModuleProxy
are both examples of using SBE to define the encoding flyweights and each has an instances of SBE encoders as fields use to converts the application types into a serialised form, before offering the encoded message onto an Aeron Publication.
The DriverProxy
in a similar manner to the DriverEventAdapter
uses the hand written flyweight do perform the encoding.
The concept of a module is less clearly defined in Aeron.
Mostly because the elements that could be considered as modules are not always named as such.
A module encapsulates a significant portion of systems functionality.
The most obvious example is the ConsensusModule
(handles the raft based consensus algorithm for Cluster), however the ClusteredServiceContainer
(runs the user defined ClusteredService
state machines), Archive
(stores streams of data to disk) and even the MediaDriver
(manages all remote and IPC communications) itself could be considered modules.
A container is a type of service used to execute some user defined code with a specific interface and lifecycle.
The only instance of a container in Aeron is the ClusteredServiceContainer
, which exists to run ClusteredService
instances.
It calls into the appropriate methods on the ClusteredService
interface whenever there is a necessary lifecycle event, e.g. start, stop, new leadership term or when a session message arrives.
A unit in Agrona's agent concurrent model.