-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #26 from osstotalsoft/feature/process_manager
add process manager
- Loading branch information
Showing
51 changed files
with
2,224 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
src/Orchestration/NBB.ProcessManager.Definition/Builder/AbstractDefinition.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
using NBB.Core.Abstractions; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
namespace NBB.ProcessManager.Definition.Builder | ||
{ | ||
public abstract class AbstractDefinition<TData> : IDefinition<TData> | ||
where TData : struct | ||
{ | ||
private readonly List<IEventActivitySet<TData>> _eventActivities = new List<IEventActivitySet<TData>>(); | ||
private readonly Dictionary<Type, EventCorrelation<IEvent, TData>> _eventCorrelations = new Dictionary<Type, EventCorrelation<IEvent, TData>>(); | ||
|
||
|
||
public EventActivitySetBuilder<TEvent, TData> StartWith<TEvent>(EventPredicate<TEvent, TData> predicate = null) | ||
where TEvent : IEvent | ||
{ | ||
var ea = new EventActivitySet<TEvent, TData>(true, predicate); | ||
_eventActivities.Add(ea); | ||
return new EventActivitySetBuilder<TEvent, TData>(ea); | ||
} | ||
|
||
public EventActivitySetBuilder<TEvent, TData> When<TEvent>(EventPredicate<TEvent, TData> predicate = null) | ||
where TEvent : IEvent | ||
{ | ||
var ea = new EventActivitySet<TEvent, TData>(false, predicate); | ||
_eventActivities.Add(ea); | ||
return new EventActivitySetBuilder<TEvent, TData>(ea); | ||
} | ||
|
||
public void Event<TEvent>(Action<EventCorrelationBuilder<TEvent, TData>> configureEventCorrelation) | ||
{ | ||
Preconditions.NotNull(configureEventCorrelation, nameof(configureEventCorrelation)); | ||
|
||
var configurator = new EventCorrelationBuilder<TEvent, TData>(); | ||
configureEventCorrelation(configurator); | ||
var correl = configurator.Build(); | ||
_eventCorrelations.Add(typeof(TEvent), new EventCorrelation<IEvent, TData>(@event => correl.CorrelationFilter((TEvent) @event))); | ||
} | ||
|
||
public Func<TEvent, object> GetCorrelationFilter<TEvent>() where TEvent : IEvent | ||
{ | ||
if (_eventCorrelations.ContainsKey(typeof(TEvent))) | ||
{ | ||
var func = _eventCorrelations[typeof(TEvent)]; | ||
return @event => func.CorrelationFilter(@event); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
public IEnumerable<Type> GetEventTypes() => _eventActivities.Select(x => x.EventType).Distinct(); | ||
|
||
public IEnumerable<ValueTuple<EventPredicate<IEvent, TData>, IEnumerable<EffectHandler<IEvent, TData>>>> GetEffectHandlers(Type eventType) | ||
{ | ||
return _eventActivities | ||
.Where(x => x.EventType == eventType) | ||
.Select(x => (x.WhenPredicate, x.GetEffectHandlers())); | ||
} | ||
|
||
public IEnumerable<ValueTuple<EventPredicate<IEvent, TData>, IEnumerable<StateHandler<IEvent, TData>>>> GetStateHandlers(Type eventType) | ||
{ | ||
return _eventActivities | ||
.Where(x => x.EventType == eventType) | ||
.Select(x => (x.WhenPredicate, x.GetStateHandlers())); | ||
} | ||
|
||
public EventPredicate<TEvent, TData> GetStarterPredicate<TEvent>() where TEvent : IEvent | ||
{ | ||
var act = _eventActivities | ||
.SingleOrDefault(x => x.EventType == typeof(TEvent) && x.StartsProcess); | ||
return (@event, data) => | ||
{ | ||
if (act == null) | ||
return false; | ||
return act.WhenPredicate?.Invoke(@event, data) ?? true; | ||
}; | ||
} | ||
|
||
public IEnumerable<EventPredicate<TEvent, TData>> GetCompletionPredicates<TEvent>() where TEvent : IEvent | ||
{ | ||
foreach (var x in _eventActivities) | ||
{ | ||
if (x.EventType == typeof(TEvent) && x.CompletesProcess) | ||
yield return (@event, data) => | ||
{ | ||
if (x.CompletionPredicate != null && x.WhenPredicate != null) | ||
return x.CompletionPredicate(@event, data) && x.WhenPredicate(@event, data); | ||
if (x.CompletionPredicate == null && x.WhenPredicate != null) | ||
return x.WhenPredicate(@event, data); | ||
if (x.CompletionPredicate != null && x.WhenPredicate == null) | ||
return x.CompletionPredicate(@event, data); | ||
return true; | ||
}; | ||
} | ||
} | ||
} | ||
} |
85 changes: 85 additions & 0 deletions
85
src/Orchestration/NBB.ProcessManager.Definition/Builder/EventActivitySet.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
using NBB.Core.Abstractions; | ||
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace NBB.ProcessManager.Definition.Builder | ||
{ | ||
|
||
public class EventActivitySet<TEvent, TData> : IEventActivitySet<TData> | ||
where TEvent : IEvent | ||
where TData : struct | ||
{ | ||
private readonly List<EffectHandler<IEvent, TData>> _handlers = new List<EffectHandler<IEvent, TData>>(); | ||
private readonly List<StateHandler<IEvent, TData>> _setStateHandlers = new List<StateHandler<IEvent, TData>>(); | ||
private readonly EventPredicate<TEvent, TData> _whenPredicate; | ||
private EventPredicate<TEvent, TData> _completionPredicate; | ||
public bool StartsProcess { get; set; } | ||
public bool CompletesProcess { get; set; } | ||
|
||
public EventActivitySet(bool startsProcess, EventPredicate<TEvent, TData> whenPredicate = null) | ||
{ | ||
StartsProcess = startsProcess; | ||
_whenPredicate = whenPredicate; | ||
} | ||
|
||
public Type EventType => typeof(TEvent); | ||
|
||
public IEnumerable<EffectHandler<IEvent, TData>> GetEffectHandlers() | ||
{ | ||
return _handlers; | ||
} | ||
|
||
public IEnumerable<StateHandler<IEvent, TData>> GetStateHandlers() | ||
{ | ||
return _setStateHandlers; | ||
} | ||
|
||
public void AddEffectHandler(EffectHandler<TEvent, TData> handler) | ||
{ | ||
_handlers.Add((@event, data) => handler((TEvent) @event, data)); | ||
} | ||
|
||
public void AddSetStateHandler(StateHandler<TEvent, TData> handler) | ||
{ | ||
_setStateHandlers.Add((@event, data) => handler((TEvent) @event, data)); | ||
} | ||
|
||
public EventPredicate<IEvent, TData> WhenPredicate | ||
{ | ||
get | ||
{ | ||
if (_whenPredicate == null) | ||
return null; | ||
return (@event, data) => _whenPredicate((TEvent) @event, data); | ||
} | ||
} | ||
|
||
public EventPredicate<IEvent, TData> CompletionPredicate | ||
{ | ||
get | ||
{ | ||
if (_completionPredicate == null) | ||
return null; | ||
return (@event, data) => _completionPredicate((TEvent) @event, data); | ||
} | ||
} | ||
|
||
public void UseForCompletion(EventPredicate<TEvent, TData> predicate) | ||
{ | ||
_completionPredicate = predicate; | ||
CompletesProcess = true; | ||
} | ||
} | ||
|
||
public interface IEventActivitySet<TData> | ||
where TData : struct | ||
{ | ||
Type EventType { get; } | ||
bool CompletesProcess { get; } | ||
bool StartsProcess { get; } | ||
EventPredicate<IEvent, TData> WhenPredicate { get; } | ||
EventPredicate<IEvent, TData> CompletionPredicate { get; } | ||
IEnumerable<EffectHandler<IEvent, TData>> GetEffectHandlers(); | ||
IEnumerable<StateHandler<IEvent, TData>> GetStateHandlers(); | ||
} | ||
} |
81 changes: 81 additions & 0 deletions
81
src/Orchestration/NBB.ProcessManager.Definition/Builder/EventActivitySetBuilder.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
using NBB.Core.Abstractions; | ||
using NBB.ProcessManager.Definition.Effects; | ||
using System; | ||
|
||
namespace NBB.ProcessManager.Definition.Builder | ||
{ | ||
public class EventActivitySetBuilder<TEvent, TData> | ||
where TEvent : IEvent | ||
where TData : struct | ||
{ | ||
private readonly EventActivitySet<TEvent, TData> _eventActivitySet; | ||
|
||
public EventActivitySetBuilder(EventActivitySet<TEvent, TData> eventActivitySet) | ||
{ | ||
_eventActivitySet = eventActivitySet; | ||
} | ||
|
||
public EventActivitySetBuilder<TEvent, TData> Then(EffectHandler<TEvent, TData> handler, EventPredicate<TEvent, TData> predicate = null) | ||
{ | ||
_eventActivitySet.AddEffectHandler((whenEvent, data) => | ||
{ | ||
if (predicate != null && !predicate(whenEvent, data)) | ||
return NoEffect.Instance; | ||
return handler(whenEvent, data); | ||
}); | ||
return this; | ||
} | ||
|
||
public EventActivitySetBuilder<TEvent, TData> SetState(StateHandler<TEvent, TData> handler, EventPredicate<TEvent, TData> predicate = null) | ||
{ | ||
_eventActivitySet.AddSetStateHandler((whenEvent, data) => | ||
{ | ||
if (predicate != null && !predicate(whenEvent, data)) | ||
return data.Data; | ||
return handler(whenEvent, data); | ||
}); | ||
return this; | ||
} | ||
|
||
public EventActivitySetBuilder<TEvent, TData> SendCommand<T>(Func<TEvent, InstanceData<TData>, T> handler, EventPredicate<TEvent, TData> predicate = null) | ||
where T : ICommand | ||
{ | ||
Then((whenEvent, state) => | ||
{ | ||
var command = handler(whenEvent, state); | ||
return new SendCommand(command); | ||
}, predicate); | ||
return this; | ||
} | ||
|
||
public EventActivitySetBuilder<TEvent, TData> RequestTimeout<T>(TimeSpan timeSpan, EventPredicate<TEvent, TData> predicate = null) | ||
where T : IEvent, new() | ||
{ | ||
RequestTimeout(timeSpan, new T(), predicate); | ||
return this; | ||
} | ||
|
||
public EventActivitySetBuilder<TEvent, TData> RequestTimeout<T>(TimeSpan timeSpan, T message, EventPredicate<TEvent, TData> predicate = null) | ||
where T : IEvent | ||
{ | ||
Then((whenEvent, state) => new RequestTimeout(state.CorrelationId.ToString(), timeSpan, message, typeof(T)), predicate); | ||
return this; | ||
} | ||
|
||
public EventActivitySetBuilder<TEvent, TData> PublishEvent<T>(Func<TEvent, InstanceData<TData>, T> handler, EventPredicate<TEvent, TData> predicate = null) | ||
where T : IEvent | ||
{ | ||
Then((whenEvent, state) => | ||
{ | ||
var @event = handler(whenEvent, state); | ||
return new PublishEvent(@event); | ||
}, predicate); | ||
return this; | ||
} | ||
|
||
public void Complete(EventPredicate<TEvent, TData> predicate = null) | ||
{ | ||
_eventActivitySet.UseForCompletion(predicate); | ||
} | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
src/Orchestration/NBB.ProcessManager.Definition/Builder/EventCorrelation.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
using System; | ||
using System.Linq.Expressions; | ||
using NBB.Core.Abstractions; | ||
|
||
namespace NBB.ProcessManager.Definition.Builder | ||
{ | ||
public class EventCorrelation<TEvent, TData> | ||
{ | ||
public Func<TEvent, object> CorrelationFilter { get; set; } | ||
|
||
public EventCorrelation(Func<TEvent, object> correlationFilter) | ||
{ | ||
CorrelationFilter = correlationFilter; | ||
} | ||
} | ||
} |
Oops, something went wrong.