I have renamed the classes from my previous example to suit the naming convention of the Disruptor-net v1.1.0 (Port of the Java Disruptor 2.7.1). Events are published by Publishers and consumed by a Consumer.
The Events (of type
Event) are Binary serilialized using ProtoBufNet and publised by multiple WCF Clients (
EventPublisher) to an WCF Service (
NetNamedPipeBinding (This can be replaced with other types of Bindings based on the need).
The Consumer consists of the
Disruptor, setup to invoke a chain of
EventHandlers in a Diamond Path configuration. The
DiamondPathEventHandlingSequencer is a simple DSL based class that encapsulates the setting of the
Disruptor for a Diamond Path event handling sequence. The
RingBuffer is filled up with instances of type
ISequencerEntry. This interface provides methods for the
IEventHandlers to read and write state of the
Event as it traverses through the Diamond Path event handling Sequence.
Three event handlers are hooked up using the
Disruptor in a Diamond Path Configuration. They resemble the architecture of LMAX explained here. They are the Journaler, UnMarshaller and Business Logic Processor. To keep the example simple I have not included the Replicator.
EventJournaler journals all incoming events to a persistant store provided by Redis.
EventAssembler deserialises the incoming Binary stream and writes the assembled Event instance back to the
EventTracker plays the role of the Business Logic Processor. In the context of this example, it just reference counts the number of events coming from each
The above 3 handlers are setup inside the
EventSequencer, a singleton wrapper over the
EventService publishes the incoming events to the
EventSequencer, which internally is publised to the
RingBuffer through the
DiamondPathEventHandlingSequencer. Subsequently the
RingBuffer takes care of invoking the Event Handlers in the appropriate sequence.
I also ran a few simple tests on my laptop, a Core i7 2.20GHz machine with 4GB memory. Below are the results.
A very trivial inference is that the Throughput of the Consumer almost equals to that of the Publiser, when there is minimal latency in the Event Handling path. So
Distruptor does its job of sequencing the events across threads in an most effective way without incurring a lock over head.
The source is available here. The Code is self explanatory. It has two parts, a Publisher and Consumer. Ensure that the Consumer is started before running the Publiser.
This had been my second adventure with
Disruptor, so any feedback on incorrect or better usage of the
Disruptor would be much appreciated.