Chronicle is simple process manager/saga pattern implementation for .NET Core that helps you manage long-living and distirbuted transactions.
master | develop | |
---|---|---|
AppVeyor | ||
CodeCov |
Chornicle is available on NuGet
Install-Package Chronicle_ -Version 3.2.1
dotnet add package Chronicle_ --version 3.2.1
In order to create and process a saga you need to go through a few steps:
- Create a class that dervies from either
Saga
orSaga<TData>
. - Inside your saga implemention, inherit from one or several
ISagaStartAction<TMessage>
andISagaAction<TMessage>
to implementHandleAsync()
andCompensateAsync()
methods for each message type. An initial step must be implemented as anISagaStartAction<TMessage>
, while the rest can beISagaAction<TMessage>
. It's worth mentioning that you can implement as manyISagaStartAction<TMessage>
as you want. In this case, the first incoming message is going to initialize the saga and any subsequentISagaStartAction<TMessage>
orISagaAction<TMessage>
will only update the current saga state. - Register all your sagas in
Startup.cs
by callingservices.AddChronicle()
. By default,AddChronicle()
will use theInMemorySagaStateRepository
andInMemorySagaLog
for maintainingSagaState
and for loggingSagaLogData
in theSagaLog
. TheSagaLog
maintains a historical record of which message handlers have been executed. Optionally,AddChronicle()
accepts anAction<ChronicleBuilder>
parameter which provides access toUseSagaStateRepository<ISagaStateRepository>()
andUseSagaLog<ISagaLog>()
for custom implementations ofISagaStateRepository
andISagaLog
. If either method is called, then both methods need to be called. - Inject
ISagaCoordinator
and invokeProcessAsync()
methods passing a message. The coordinator will take care of everything by looking for all implemented sagas that can handle a given message. - To complete a successful saga, call
CompleteSaga()
orCompleteSagaAsync()
. This will update theSagaState
to Completed. To flag a saga which has failed or been rejected, call theReject()
orRejectAsync()
methods to update theSagaState
to Rejected. Doing so will utilize theSagaLog
to call each message type'sCompensateAsync()
in the reverse order of their respectiveHandleAsync()
method was called. Additionally, an unhanded exception thrown from aHandleAsync()
method will causeReject()
to be called and begin the compensation.
Below is the very simple example of saga that completes once both messages (Message1
and Message2
) are received:
public class Message1
{
public string Text { get; set; }
}
public class Message2
{
public string Text { get; set; }
}
public class SagaData
{
public bool IsMessage1Received { get; set; }
public bool IsMessage2Received { get; set; }
}
public class SampleSaga : Saga<SagaData>, ISagaStartAction<Message1>, ISagaAction<Message2>
{
public Task HandleAsync(Message1 message, ISagaContext context)
{
Data.IsMessage1Received = true;
Console.WriteLine($"Received message1 with message: {message.Text}");
CompleteSaga();
return Task.CompletedTask;
}
public Task HandleAsync(Message2 message, ISagaContext context)
{
Data.IsMessage2Received = true;
Console.WriteLine($"Received message2 with message: {message.Text}");
CompleteSaga();
return Task.CompletedTask;
}
public Task CompensateAsync(Message1 message, ISagaContext context)
=> Task.CompletedTask;
public Task CompensateAsync(Message2 message, ISagaContext context)
=> Task.CompletedTask;
private void CompleteSaga()
{
if(Data.IsMessage1Received && Data.IsMessage2Received)
{
Complete();
Console.WriteLine("SAGA COMPLETED");
}
}
}
Both messages are processed by mentioned coordinator:
var coordinator = app.ApplicationServices.GetService<ISagaCoordinator>();
var context = SagaContext
.Create()
.WithCorrelationId(Guid.NewGuid())
.Build();
coordinator.ProcessAsync(new Message1 { Text = "Hello" }, context);
coordinator.ProcessAsync(new Message2 { Text = "World" }, context);
The result looks as follows:
If you're looking for documentation, you can find it here.
Icon made by Smashicons from www.flaticon.com is licensed by Creative Commons BY 3.0
chronicle's People
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.