Magnum


State Machine


Introduction

The state machine is a common pattern in software development. 

An event driven state machine is a composition of states, events, and transitions that form a model of reactive behavior. Events are delivered to the state machine in the form of messages, resulting in the execution of logic dependent upon the current state of the machine.

This is in contrast to the reference definition of a finite state machine which originates in parsing theory and typically deals with the consumption of tokens. Instead of parsing an input stream, an event driven state machine reacts to events that are raised by external stimuli.



Behavior is defined in terms of how the state machine is defined, the event that is applied, and the current state of the machine at the time the event is applied.

For each state, behavior is defined for each event that can occur during the specific state. 


Defining a state transition that should occur after the successful execution of the behavior tied to a state/event pair allows the machine to define a process flow. If the defined behavior throws an exception, an alternate transition can be specified reflecting an alternate path through the state machine as a result of the exception.





State

State

A state





Event

Event

An event





Transition

Transition

A transition



Handling Exceptions

It’s a known fact that bad things happen. How an application reacts when unexpected things happen can have a huge impact on whether the application is a success. When using the state machine, exception handlers can be defined for each Then expression used.


During(Outdated,

When(CustomerUpdated)

.Then((details, message) => details.UpdateCustomerDetails(message.Customer),

InCaseOf<Exception>()

.TransitionTo(Suspect))

.TransitionTo(Current));




Visualization


Testing


Pipeline


Introduction

The event aggregator pattern (GoF) specifies that …



The Magnum Pipeline implements several integration patterns








Event Aggregation



By adding a Magnum pipeline to your dependency injection container with a singleton lifestyle, it is easy to programatically add subscriptions to events.


Instead of injecting the pipeline as a dependency in your class, you may instead implement one of the consumer interfaces. 


IConsumer<T> has a single method Consume with the message as an argument.


IAsyncConsumer<T> also has a single method Consume with the same signature but specifies that the message should be consumed asynchronously. 



Subscriptions



Consumers


Introduction

A consumer is a method, object, or component that is called when a message is sent to the pipeline.

In order for a consumer to receive a message, it must subscribe to a pipeline.


Methods

A method can be a method on an object instance, an anonymous method or a lambda expression.

Methods are subscribed to the pipeline using the Subscribe method on the SubscriptionScope.


scope.Subscribe<CustomerUpdated>(message => {});



Once subscribed, the method will be called once for every message that is sent to the pipeline.





Objects

An object is an instance of a class that contains at least one consumer interface.

When an object instance is passed to the Subscribe method, the object type is used to identify and wire consumer methods to the pipeline. If the object implements the IConsumer<T> or IAsyncConsumer<T> interface, the Consume method of that interface implementation will be called once for every message that is sent to the pipeline.





Components

A component is a class that implements at least one consumer interface.

Subscribing a component to the pipeline is similar to subscribing an object instance in terms of how the message consumers are identified and wired to the pipeline. In the case of a component, however, a new object instance is created to consumer each message that is sent to the pipeline.

This is useful in situations where the object consuming the message has dependencies that need to be satisfied at runtime (such as a database session). By taking a dependency on an NHibernate ISession instead of opening a session as part of the message consumer, the object can easily participate in an existing unit of work that may have been started by an interceptor or the producer of the message.


Filters

A filter…




Asynchronous Consumers

An asynchronous consumer is a message consumer that is delivered messages in a separate thread from the thread where the message was produced.



To ease the concurrency requirements of an asynchronous message consumer, messages are delivered to the consumer one at a time in the order that they were sent.


Aside from the thread on which the message is delivered, the messages are delivered to the consumer in the same way. If the consumer is a method or an object instance, the consumer method is called for each message. If the consumer is a component, a new instance of the component is created and called for each message.

Internally as each message is sent through the pipeline, a block containing the delivery of the message to the consumer is stored on a queue. If this is the first message delivered to the consumer, a method is delegated to the ThreadPool using the ThreadPool.QueueUserWorkItem method.






Interceptors


Visualization

To make it easier to troubleshoot the pipeline there are visualizers to display the composition of the pipeline, including both consumers and internal routing segments. 




Trace Visualizer

The trace visualizer can be useful during test driven development to get a quick snapshot of the pipeline consumers and interceptors have been added. This can really reduce the number of forehead slaps per hour when it comes to less than obvious coding mistakes. 



Model Visualizer

The model visualizer (coming soon) is useful to publish the composition of the pipeline for display by an external visualization tool, such as a visual user interface or a graph. By generating an object graph that can be serialized, the composition can be delivered to a remote system using MassTransit, WCF, or some other communication framework.



Graph Visualizer

The graph visualizer (coming soon) generates an image with a graphical representation of the pipeline composition.


General


Actors