asynchronous.net applications with nservicebus david de florinier ([email protected]) gojko...
TRANSCRIPT
Asynchronous .NET applications with
NServiceBus
David de Florinier ([email protected])
Gojko Adzic ([email protected])
Skills Matter 27/11/2008
Fire and forget
Use when the second part of a process has to be completed, but we don't really have to wait for it to finish. This typically involves an external system or batch processing.
Resilience Easier to test Option to go offline
Just leave it there when you're done
Use when the second part of a process is slow or talks to an external system, but completing the task is important to continue the work.
Better UI responsiveness Performance Better resource usage
Share the load
Use when lots of different agents can submit or process work. Decouple workers and requesters.
Performance Scalability More flexible Easier to extend
Who? ... What? ...Where?
Written by Udi Dahan It is an open source communications framework Get it from http://www.nservicebus.com Released under the Apache Licence 2.0 Current Release is 1.8
Getting Started
Download from http://www.nservicebus.com/Downloads.aspx
Extract the files from the zip, then build using build.bat (this uses msbuild)
The assemblies will now be in the build folder (and subfolders)
Look through the Sample projects, these cover all the simple usage cases (for Spring)
IBuilder
Various parts of the framework (e.g. passing messages to handlers) use a service locator pattern.
This is done using the IBuilder interface An implementation using Spring is provided:
ObjectBuilder.SpringFramework An example of a implementation for Castle
Windsor is in the Demo source
ITransport
Responsibility for sending and receiving messages is delegated to a transport component
Unicast Implementations for MSMQ and Http are provided
There is an IMulticastTransport interface, but there are no implementations provided
IMessageSerializer
Responsibilty for serialization of messages is delegated to a serialization component
Implementations for Binary and Xml serialization are provided
Has the following methods void Initialize(params Type[] types);
void Serialize(IMessage[] messages, Stream stream);
IMessage[] Deserialize(Stream stream);
IBus
The entry point for your code Send, Subscribe, Unsubscribe, Publish IUnicastBus and IMulticastBus interfaces inherit
from IBus, Use IUnicastBus with IUnicastTransport Use IMulticastBus IMulticastTransport
Publish/Subscribe
Messages should implement the IMessage marker interface
Use IBus.Publish(IMessage)
Use IBus.Subscribe(Type[,predicate])
Message handlers implement IMessageHandler<T>
Implement IBuilder interface to create an handler builder if not using Spring.Net
ISubscriptionStorage
Needs to be configured for publishers Persistence and retrieval of subscriptions is
delegated to ISubscriptionStorage Db and Msmq implementations are provided Db implementation allows multiple publisher
instances to share one subscription store
Publish/Subscribe config Always needed
Transport : NumberOfWorkerThreads, IsTransactional, InputQueue
Bus: ITransport, IMessageSerializer.
On Publisher:
SubscriptionStorage : persistence for subscriptions
Bus: ISubscriptionStorage
On Subscriber
Transport : NumberOfWorkerThreads, IsTransactional, InputQueue
no need for ISubscriptionStorage.
IBuilder must be able to build Handlers
Bus: MessageOwners: where subscription messages are sent
Bus: AddTypesFromAssembly for handler types
Full Duplex
Use IBus.Send(IMessage).Register(Callback) to make asynchronous request
Use IBus.Reply(Response) to send response
Full Duplex code
Sending message from the client
bus.Send(["worker@localhost", ]msg).Register(callback, msg);
Handling the message on the server_bus.Reply(response);
Handling the callback on the clientprivate void callback(IAsyncResult ar) {
....
CompletionResult result = asyncResult.AsyncState as CompletionResult;
Message request = result.State as Message;
...foreach (var message in result.Messages) { ...}
....
}
Saga
Framework for long lived message workflows Saga Messages implement ISagaMessage Implement ISaga<T> to handle saga messages NserviceBus.Testing.Saga contains Mock objects for use
in unit tests
ISagaPersister
The responsibility of persisting and rehydrating Saga entities is delegated to a class implementing ISagaPersister
DbBlobSagaPersister implementation provided
ISaga<T>
Saga Enitity, which will handle the various steps in the saga workflow, will implement ISaga<T> for each workflow step
Also a class extending SagaMessageHandler may be used. This will typically override the Handle and NeedToHandle methods.
The SagaMessageHandler uses ISagaPersister to rehydrate the ISaga<T> implementation, and call it's Handle method
Distributor
A way of scaling costly transactions
Workers report for work Distributor sends work to
first available worker When workers have
completed, they report for work again
An executable is provided
Conclusions Positives
Source code is well structured and easy to understand
Main objects can be extended, flexible architecture Has performed well in load tests Few dependencies
Negatives There is little documentation
Some alternatives?
ActiveMQ and NMS
http://activemq.apache.org/nms.html SimpleServiceBus
http://www.codeplex.com/SimpleServiceBus MassTransit
http://code.google.com/p/masstransit/
Links
http://www.nservicebus.com http://www.udidahan.com http://ayende.com/Blog/archive/2008/03/24/
NServiceBus-Review.aspx http://gojko.net
Next events
TDD in .NET, 17/Dec OpenSource .NET Exchange 22/Jan Fitnesse.NET tips and tricks, 17/Feb For more info: http://ukdotnet.ning.com/