private async Task CheckEvent(IProcessExpectedEvent expectedEvent, IProcessSystemMessage message) { //todo: good implimentation of Railway pattern chain execution with error handling if (!expectedEvent.EventPredicate.Invoke(message)) { return; } expectedEvent.Validate(message); InMessages.AddOrUpdate(expectedEvent.Key, message, (k, v) => message); if (ComplexEventAction.ActionTrigger != ActionTrigger.Any && InMessages.Count() != ComplexEventAction.Events.Count) { return; } await ExecuteAction(InMessages.ToImmutableDictionary(x => x.Key, x => x.Value as object)).ConfigureAwait(false); if (ComplexEventAction.ActionTrigger == ActionTrigger.All) { InMessages.Clear(); } else { IProcessSystemMessage msg; InMessages.TryRemove(expectedEvent.Key, out msg); } }
public ProcessEventFailure(Type failedEventType, IProcessSystemMessage failedEventMessage, Type expectedEventType, Exception exception, IStateEventInfo processInfo, ISystemSource source) : base(processInfo, failedEventMessage.Process, source) { FailedEventType = failedEventType; //TODO: need to implement serialization //FailedEventMessage = failedEventMessage; ExpectedEventType = expectedEventType; Exception = exception; }
private void HandleProcessEvents(IProcessSystemMessage pe) { // Log the message //TODO: Reenable event log //Persist(pe, x => { });//(x) => msgQue.Add(x) // send out Process State Events msgQue.Enqueue(pe); }
public EntityDataServiceSupervisor(ISystemProcess process, IProcessSystemMessage msg) : base(process) { ctx = Context; foreach (var itm in entityEvents) { this.GetType() .GetMethod("CreateEntityActor") .MakeGenericMethod(itm.Key) .Invoke(this, new object[] { itm.Value, process, msg }); } }
public EntityViewDataServiceActor(ICreateEntityViewService msg, IProcessSystemMessage firstMsg) : base(msg.Process) { Action = (Action <TService>)msg.Action; // Command<TService>(m => HandledEvent(m)); if (firstMsg is TService) { HandledEvent((TService)firstMsg); } EventMessageBus.Current.GetEvent <TService>(Source).Subscribe(x => HandledEvent(x)); EventMessageBus.Current.Publish(new ServiceStarted <IEntityViewDataServiceActor <TService> >(this, new StateEventInfo(msg.Process.Id, RevolutionData.Context.Actor.Events.ActorStarted), msg.Process, Source), Source); }
internal static void PublishProcesError(IProcessSystemMessage msg, Exception ex, Type expectedMessageType) { var outMsg = new ProcessEventFailure(failedEventType: msg.GetType(), failedEventMessage: msg, expectedEventType: expectedMessageType, exception: ex, source: Source, processInfo: new StateEventInfo(msg.Process.Id, RevolutionData.Context.Process.Events.Error)); Logger.Log(LoggingLevel.Error, $"Error:ProcessId:{msg.ProcessInfo.ProcessId}, ProcessStatus:{msg.ProcessInfo.State.Status}, ExceptionMessage: {ex.Message}|||| {ex.StackTrace}"); EventMessageBus.Current.Publish(outMsg, Source); }
// private static ConcurrentDictionary<IProcessExpectedEvent, bool> RaisedExpectedEvents { get; } = new ConcurrentDictionary<IProcessExpectedEvent, bool>(); public static bool Validate(this IProcessExpectedEvent expectedEvent, IProcessSystemMessage msg) { var raised = expectedEvent.EventPredicate.Invoke(msg); if (!raised) { return(false); } msg.ValidatedBy(expectedEvent); // RaisedExpectedEvents.AddOrUpdate(expectedEvent, true, (k, c) => true); return(true); }
public EntityViewDataServiceSupervisor(ISystemProcess process, IProcessSystemMessage msg) : base(process) { try { ctx = Context; Parallel.ForEach(entityEvents, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, (itm) => { this.GetType() .GetMethod("CreateEntityViewActor") .MakeGenericMethod(itm.Key) .Invoke(this, new object[] { itm.Value, process, msg }); }); } catch (Exception) { throw; } }
private void HandleProcessViews(IProcessSystemMessage pe) { try { Parallel.ForEach(ProcessViewModelInfos.Where(x => x.ProcessId == pe.Process.Id), new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, (v) => { var msg = new LoadViewModel(v, new StateCommandInfo(pe.Process.Id, RevolutionData.Context.ViewModel.Commands.LoadViewModel), pe.Process, Source); EventMessageBus.Current.Publish(msg, Source); }); } catch (Exception ex) { //todo: need to fix this PublishProcesError(pe, ex, pe.GetType()); } }
internal void Publish(IProcessSystemMessage msg) { EventMessageBus.Current.Publish(msg, Source); OutMessages = OutMessages.Add(msg); }
private void CreateEntityViewActors(Type classType, Type genericListType, string actorName, ISystemProcess process, IProcessSystemMessage msg) { var child = ctx.Child(string.Format(actorName, classType.Name)); if (!Equals(child, ActorRefs.Nobody)) { return; } var specificListType = genericListType.MakeGenericType(classType); try { Task.Run(() => { ctx.ActorOf(Props.Create(specificListType, process, msg), string.Format(actorName, classType.Name)); }).ConfigureAwait(false); } catch (Exception ex) { Debugger.Break(); EventMessageBus.Current.Publish(new ProcessEventFailure(failedEventType: msg.GetType(), failedEventMessage: msg, expectedEventType: typeof(ServiceStarted <>).MakeGenericType(specificListType), exception: ex, source: Source, processInfo: new StateEventInfo(msg.Process.Id, RevolutionData.Context.Process.Events.Error)), Source); } }
public static void ValidatedBy(this IProcessSystemMessage msg, IProcessExpectedEvent expectedEvent) { MessageExpectedEvents.AddOrUpdate(msg, expectedEvent, (x, v) => expectedEvent); }
public static bool IsValid(this IProcessSystemMessage msg) { return(MessageExpectedEvents.ContainsKey(msg)); }
public void CreateEntityActor <TEvent>(object action, ISystemProcess process, IProcessSystemMessage msg) where TEvent : IMessage { /// Create Actor Per Event Type actorType = typeof(EntityDataServiceActor <>).MakeGenericType(typeof(TEvent)); var inMsg = new CreateEntityService(actorType, action, new StateCommandInfo(process.Id, RevolutionData.Context.Actor.Commands.StartActor), process, Source); try { Task.Run(() => { ctx.ActorOf( Props.Create(actorType, inMsg, msg) .WithRouter(new RoundRobinPool(1, new DefaultResizer(1, Environment.ProcessorCount, 1, .2, .3, .1, Environment.ProcessorCount))), "EntityDataServiceActor-" + typeof(TEvent).GetFriendlyName().Replace("<", "'").Replace(">", "'")); }); } catch (Exception ex) { //ToDo: This seems like a good way... getting the expected event type PublishProcesError(inMsg, ex, inMsg.ProcessInfo.State.ExpectedEvent.GetType()); } }
public static Dictionary <string, string> GetDerivedProperties(this IProcessSystemMessage msg) { FieldInfo[] fields = msg.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance); return(fields.ToDictionary(f => f.Name, f => new JavaScriptSerializer().Serialize(f.GetValue(msg)))); }
public void CreateEntityViewActor <TEvent>(object action, ISystemProcess process, IProcessSystemMessage msg) where TEvent : IMessage { Type actorType = typeof(EntityViewDataServiceActor <>).MakeGenericType(typeof(TEvent)); var inMsg = new CreateEntityViewService(actorType, action, new StateCommandInfo(process.Id, RevolutionData.Context.Actor.Commands.StartActor), process, Source); EventMessageBus.Current.Publish(inMsg, Source); /// Create Actor Per Event try { Task.Run(() => { ctx.ActorOf( Props.Create(inMsg.ActorType, inMsg, msg) .WithRouter(new RoundRobinPool(1, new DefaultResizer(1, Environment.ProcessorCount, 1, .2, .3, .1, Environment.ProcessorCount))), "EntityViewDataServiceActor-" + typeof(TEvent).GetFriendlyName().Replace("<", "'").Replace(">", "'")); }); //_childActor.Tell(msg); } catch (Exception ex) { Debugger.Break(); EventMessageBus.Current.Publish(new ProcessEventFailure(failedEventType: inMsg.GetType(), failedEventMessage: inMsg, expectedEventType: typeof(ServiceStarted <>), exception: ex, source: Source, processInfo: new StateEventInfo(process.Id, RevolutionData.Context.Process.Events.Error)), Source); } }