/// <summary> /// Constructor /// </summary> /// <param name="msg">The paired incoming message</param> /// <param name="status">Extra status information</param> //public MySimpleOkResponse(MyBaseMsg msg, string status) //: base(MyMsgType.SimpleResponse, msg, MyReturnCode.Success, status) { public MySimpleOkResponse(ISpEventMessage msg, string status) : base(MyMsgType.SimpleResponse, MyEventType.Tick, SpEventPriority.Normal) { this.ReturnCode = SpConverter.EnumToInt(MyReturnCode.Success); this.ReturnStatus = status; this.Uid = msg.Uid; }
/// <summary> /// Get a clone of the transition object from the store or null if not found /// </summary> /// <param name="store">The store to search</param> /// <param name="eventMsg">The message to insert in the transition object</param> /// <returns>The transition object from the store or null if not found</returns> public static ISpStateTransition GetTransitionCloneFromStore(Dictionary<int, ISpStateTransition> store, ISpEventMessage eventMsg) { WrapErr.ChkParam(store, "store", 51009); WrapErr.ChkParam(eventMsg, "eventMsg", 51010); return WrapErr.ToErrorReportException(51011, () => { if (store.Keys.Contains(eventMsg.EventId)) { // Clone Transition object from store since its pointers get reset later ISpStateTransition tr = (ISpStateTransition)store[eventMsg.EventId].Clone(); if (tr.ReturnMessage == null) { tr.ReturnMessage = eventMsg; } else { //Log.Info("SpTools", "GetTransitionCloneFromStore", "Found a transition AND - Held msg - transfering GUID"); } // TODO - Look at transfering the GUID here tr.ReturnMessage.Uid = eventMsg.Uid; //tr.ReturnMessage = eventMsg; return tr; } return null; }); }
/// <summary> /// Add and event object to the store /// </summary> /// <param name="msg">The message event</param> public void Add(ISpEventMessage msg) { WrapErr.ChkDisposed(this.disposed, 50111); WrapErr.ChkParam(msg, "msg", 50112); lock (this.queueLock) { this.AddEvent(msg); } }
// TODO - remove this - do not want to copy the event id automatically ?? public SpBaseEventResponse(ISpToInt typeId, ISpEventMessage msg, ISpToInt returnCode, string returnStatus) : base(typeId, new SpIntToInt(msg.EventId)) { // Transfer the message guid to the response for correlation this.Uid = msg.Uid; this.ReturnCode = returnCode.ToInt(); this.ReturnStatus = ReturnStatus; }
private ISpEventMessage Tick(ISpEventMessage msg, ISpStateMachine sm) { ISpEventMessage?ret = null; TestHelpers.CatchUnexpected(() => { ret = sm.Tick(msg); }); return(ret); }
/// <summary> /// Called on every other period after the first /// </summary> /// <param name="msg">The incoming message</param> /// <returns>A state transition object</returns> public virtual ISpStateTransition OnTick(ISpEventMessage msg) { //Log.Info(this.className, "OnTick", String.Format("'{0}' State - {1}", this.FullName, this.ConvertEventIdToString(msg.EventId))); WrapErr.ChkTrue(this.IsEntryExcecuted, 50205, () => { return(String.Format("OnTick for '{0}' State Cannot be Executed Before OnEntry", this.FullName)); }); return(WrapErr.ToErrorReportException(9999, () => { return this.GetTransition(false, this.ExecOnTick, msg); })); }
protected override ISpEventMessage ExecOnTick(ISpEventMessage msg) { Log.Info(this.className, "ExecOnTick", String.Format("With event:{0}", this.GetCachedEventId(msg.EventId))); if (SpConverter.IntToEnum<MyEventType>(msg.EventId) == MyEventType.Abort) { Log.Info(this.className, "ExecOnTick", String.Format("Exiting with event {0}", MyEventType.ExitAborted)); return ExecOnEntry(new MyBaseMsg(MyMsgType.SimpleResponse, MyEventType.ExitAborted)); } Log.Info(this.className, "ExecOnTick", "Exiting with default event"); return base.ExecOnEntry(msg); }
protected override ISpEventMessage ExecOnTick(ISpEventMessage msg) { this.counter++; this.log.Info("ExecOnTick", () => string.Format("Count:{0}", this.counter)); if (this.counter > 2) { this.log.Info("ExecOnTick", "RETURN DONE"); return(new MyDoneMsg()); } return(base.ExecOnTick(msg)); }
/// <summary> /// Pop the next event object from the store /// </summary> /// <returns>The T object</returns> public ISpEventMessage Get() { WrapErr.ChkDisposed(this.disposed, 50113); // Make stack variable and only lock the queue for the duration of the copy to // free it up for other threads to add events ISpEventMessage eventCopy = null; lock (this.queueLock) { eventCopy = this.GetEvent(); } return(eventCopy == null ? this.defaultTick : eventCopy); }
private ISpStateTransition GetSuperStateOnEventTransition(ISpEventMessage msg) { ISpStateTransition tr = this.GetOnEventTransition(msg); if (tr != null) { tr.ReturnMessage = (tr.ReturnMessage == null) ? this.MsgFactory.GetResponse(msg) : this.MsgFactory.GetResponse(tr.ReturnMessage); } return(tr); }
/// <summary>Safely execute function and transfer the GUID to the response</summary> /// <param name="msg">The incoming message</param> /// <param name="func">The function to invoke to generate the response message</param> /// <returns>A correlated response message</returns> private ISpEventMessage GetMsg(ISpEventMessage msg, Func <ISpEventMessage> func) { WrapErr.ChkParam(msg, "msg", 9999); return(WrapErr.ToErrorReportException(9999, () => { ISpEventMessage ret = func.Invoke(); WrapErr.ChkVar(ret, 9999, "The Provider Returned a Null Message"); // Transfer the GUID for correlation ret.Uid = msg.Uid; return ret; })); }
/// <summary> /// Factor out the reporting of state transitions for clarity /// </summary> /// <param name="tr">The transition object</param> /// <param name="eventMsg">The event message which pushed this transition</param> private void LogTransition(ISpStateTransition tr, ISpEventMessage eventMsg) { WrapErr.ToErrorReportException(9999, () => { Log.Debug("SpState", "LogTransition", String.Format( "{0} OnMsg({1} - {2}) - From:{3} To:{4}", tr.TransitionType, this.GetCachedMsgTypeId(eventMsg.TypeId), this.GetCachedEventId(eventMsg.EventId), this.FullName, tr.NextState == null ? "Unknown" : tr.NextState.FullName)); }); }
protected override ISpEventMessage ExecOnTick(ISpEventMessage msg) { Log.Info(this.className, "ExecOnTick", this.FullName + " ********************************************** "); if (This.DoIFlipStates) { // TODO - rework msg to allow creation of a msg with another msg to transfer correlation GUID Log.Info(this.className, "ExecOnTick", "Exceeded trigger count, ** changing msg to Start"); MyBaseMsg newMsg = new MyBaseMsg(MyMsgType.SimpleMsg, MyEventType.Start); newMsg.Uid = msg.Uid; //return base.ExecOnTick(newMsg); } return msg; //return base.ExecOnEntry(msg); }
public ISpEventMessage Response(ISpEventMessage msg) { MyMsgId eventType = SpConverter.IntToEnum <MyMsgId>(msg.EventId); MyMsgType msgType = SpConverter.IntToEnum <MyMsgType>(msg.TypeId); // All my messages are Simple Types so I do not need any other info for types. Otherwise I would need a switch return(new MyBaseMsg(msgType, eventType, msg.Priority) { ReturnCode = msg.ReturnCode, StringPayload = msg.StringPayload, ReturnStatus = msg.ReturnStatus }); }
protected override ISpEventMessage ExecOnTick(ISpEventMessage eventMsg) { // If all IO is on, return message if (this.outputs.GetState(OutputId.GasNitrogen) == IOState.On && this.outputs.GetState(OutputId.GasOxygen) == IOState.On) { Log.Warning(2, "******* Everyting is ON **********"); return(new MsgInitComplete()); } // Still waiting Log.Warning(3, "******* STILL WAITING **********"); return(base.ExecOnTick(eventMsg)); }
/// <summary> /// Safely execute the function and transfer the GUID to the response /// </summary> /// <param name="msg">The incoming message</param> /// <param name="func">The function to invoke to generate the response message</param> /// <returns>A correlated response message</returns> private ISpEventMessage GetMsg(ISpEventMessage msg, Func<ISpEventMessage> func) { WrapErr.ChkParam(msg, "msg", 9999); return WrapErr.ToErrorReportException(9999, () => { ISpEventMessage ret = func.Invoke(); WrapErr.ChkVar(ret, 9999, "The Provider Returned a Null Message"); // Transfer the GUID for correlation ret.Uid = msg.Uid; return ret; }); }
/// <summary> /// Retrieve the transition object from the OnResults queue of the super state /// </summary> /// <param name="msg"></param> /// <returns></returns> private ISpStateTransition GetSuperStateOnResultTransition(ISpEventMessage msg) { // Check super state registered result transitions against Sub State event id ISpStateTransition tr = this.GetOnResultTransition(msg); WrapErr.ChkVar(tr, 9999, () => { return(String.Format( "State {0} Specified Exit but SuperState {1} has no handlers for that event id:{2}", this.currentState.FullName, this.FullName, this.GetCachedEventId(msg.EventId))); }); tr.ReturnMessage = this.MsgFactory.GetResponse(msg, tr.ReturnMessage); return(tr); }
protected override ISpEventMessage ExecOnEntry(ISpEventMessage eventMsg) { if (this.outputs.GetState(OutputId.Heater) == IOState.On) { // Bad, should have been turned off // return unrecoverable error } // Set IO to entry values //this.inputs.SetState(InputId.Heater, IOState.Off); // this done on recovery this.inputs.SetState(InputId.GasNitrogen, IOState.On); this.inputs.SetState(InputId.GasOxygen, IOState.On); return(base.ExecOnEntry(eventMsg)); }
/// <summary> /// Handle Defered transition objects from both the current substate and this super state /// </summary> /// <param name="tr">The current transition object</param> /// <param name="msg"></param> /// <param name="fromSuperState"> /// true if the Transition if from the super state, false if from the substate /// </param> /// <returns>The Transition</returns> private ISpStateTransition HandleDeferedStateTransitionType(ISpStateTransition tr, ISpEventMessage msg, bool fromSuperState) { // If the superstate iteself has a Defered transition it will return immediately to parent if (fromSuperState) { return(tr); } // Call super state override method that derived superstate will use to handle decision point and create a new message with event ISpEventMessage deferedMsg = this.OnRuntimeTransitionRequest(msg); // Process the transition type from the SubState level return(this.ReadTransitionType( this.GetSuperStateOnResultTransition(deferedMsg), deferedMsg, true)); }
protected override ISpEventMessage ExecOnTick(ISpEventMessage eventMsg) { // If all IO is on, return message if (this.outputs.GetState(OutputId.Heater) == IOState.Off && this.outputs.GetState(OutputId.GasNitrogen) == IOState.Off && this.outputs.GetState(OutputId.GasOxygen) == IOState.Off) { return(new DemoMsgBase(DemoMsgType.SimpleMsg, DemoMsgId.RecoveryComplete) { Uid = eventMsg.Uid }); } // Still waiting return(base.ExecOnTick(eventMsg)); }
/// <summary> /// Execute on each tick period /// </summary> /// <param name="msg">The incoming message with event</param> /// <returns>The return transition object with result information</returns> public sealed override ISpStateTransition OnTick(ISpEventMessage msg) { //Log.Info(this.className, "OnTick", String.Format("'{0}' State", this.FullName)); WrapErr.ChkVar(this.entryState, 9999, "The 'SetEntryState() Must be Called in the Constructor"); WrapErr.ChkVar(this.currentState, 9999, "Current state is not set"); WrapErr.ChkTrue(this.IsEntryExcecuted, 9999, "Tick Being Called before OnEntry"); // If there are OnEvent transitions registered at the superstate level return immediately ISpStateTransition tr = GetSuperStateOnEventTransition(msg); if (tr != null) { return(tr); } return(this.GetTransition(this.currentState.OnTick, msg)); }
/// <summary> /// Execute logic on entry into this superstate /// </summary> /// <param name="msg">The incoming message with event</param> /// <returns>The return transition object with result information</returns> public sealed override ISpStateTransition OnEntry(ISpEventMessage msg) { Log.Info(this.className, "OnEntry", String.Format("'{0}' State Event {1}", this.FullName, this.GetCachedEventId(msg.EventId))); WrapErr.ChkVar(this.entryState, 9999, "The 'SentEntryState() Must be Called in the Constructor"); // Find if there are exit conditions OnEntry at the SuperState level and excecute them first // This will check OnEvent transitions queue and transitions from the overriden ExecOnEntry ISpStateTransition t = base.OnEntry(msg); if (t.TransitionType != SpStateTransitionType.SameState) { return(t); } // return transition this.currentState = this.entryState; return(this.currentState.OnEntry(msg)); }
public ISpEventMessage Response(ISpEventMessage msg, ISpEventMessage?registeredMsg) { if (registeredMsg == null) { return(this.Response(msg)); } // In this scenario we would make a copy of the registered msg and copy in the data from the original incoming message // We only have simple messages. Now we can change the data from the cloned message stored in the transition with // the incoming message data. We will preserve the event and message type from stored object ISpEventMessage ret = this.Response(registeredMsg); ret.Priority = msg.Priority; ret.ReturnCode = msg.ReturnCode; ret.ReturnStatus = msg.ReturnStatus; ret.StringPayload = msg.StringPayload; return(ret); }
/// <summary> /// Add an event to the proper priority queue /// </summary> /// <param name="msg">The msg to add</param> protected override void AddEvent(ISpEventMessage msg) { switch (msg.Priority) { case SpEventPriority.Low: this.lowPriorityQueue.Enqueue(msg); break; case SpEventPriority.Normal: this.NormalPriorityQueue.Enqueue(msg); break; case SpEventPriority.High: this.HighPriorityQueue.Enqueue(msg); break; case SpEventPriority.Urgent: this.UrgentPriorityQueue.Enqueue(msg); break; default: WrapErr.ChkTrue(false, 50150, String.Format("The Priority Type '{0}' is not Handled", msg.Priority)); break; } }
/// <summary> /// Read the transition object to determine behavior /// </summary> /// <param name="tr">The transition object</param> /// <param name="msg">the current event message</param> /// <param name="superStateLevelEvent"> /// true if the transition object is from the current substate, false if the transition was generated /// by the superstate based on a previous Defered Transition type generated from the substate. This /// prevents infinite recursion. /// </param> /// <returns>A Transtion object with the results of the state processing</returns> ISpStateTransition ReadTransitionType(ISpStateTransition tr, ISpEventMessage msg, bool superStateLevelEvent) { WrapErr.ChkVar(tr, 9999, "The transition is null"); switch (tr.TransitionType) { case SpStateTransitionType.SameState: return(tr); case SpStateTransitionType.NextState: return(this.HandleNextStateTransitionType(tr, msg)); case SpStateTransitionType.ExitState: return(this.HandleExitStateTransitionType(msg)); case SpStateTransitionType.Defered: return(this.HandleDeferedStateTransitionType(tr, msg, superStateLevelEvent)); default: WrapErr.ChkTrue(false, 9999, String.Format("Transition Type {0} not Handled", tr.TransitionType)); return(tr); } }
/// <summary> /// Handle the substate ExitState Transition Type by using the event msg passed to it to do a lookup /// of this super state's transitions. The super state should have a transition that has been /// registered to the same id /// </summary> /// <param name="msg"></param> /// <returns></returns> private ISpStateTransition HandleExitStateTransitionType(ISpEventMessage msg) { Log.Info(this.className, "HandleExitStateTransitionType", String.Format("'{0}' State", this.FullName)); // TODO - this is really only another kind of defered. The difference is that the superstate does not // TODO called at runtime to handle the event. Rather the event is passed to the super state's // TODO registered events. In this scenario it may not actually exit the super state but process // the event id to something else. The difference is that the results are being determined // by the registrations at the superstate level rather than the sub state level // Check super state registered result transitions against Sub State event id ISpStateTransition tr = this.GetSuperStateOnResultTransition(msg); WrapErr.ChkVar(tr, 9999, () => { return(String.Format( "State {0} Specified Exit but SuperState {1} has no handlers for that event id:{2}", this.currentState.FullName, this.FullName, this.GetCachedEventId(msg.EventId))); }); // At this point, the transition registered to the superstate should have everything set in it return(tr); }
//protected override ISpEventMessage ExecOnTick(ISpEventMessage eventMsg) { // Console.WriteLine("########## {0} has received OnTick event:{1}", this.FullName, eventMsg.EventId); // return base.ExecOnEntry(eventMsg); // // just push the same one back // //return eventMsg; //} //protected override ISpEventMessage ExecOnTick(ISpEventMessage eventMsg) { // Console.WriteLine("########## {0} has received OnTick event:{1}", this.FullName, eventMsg.EventId); // return base.ExecOnEntry(eventMsg); // // just push the same one back // //return eventMsg; //} #region SpStateOverrides protected override ISpEventMessage OnRuntimeTransitionRequest(ISpEventMessage msg) { switch (SpConverter.IntToEnum <MyMsgId>(msg.EventId)) { case MyMsgId.Abort: Log.Info("MySuperState", "OnRuntimeTransitionRequest", " *** Got abort and returning Stop"); // get the GUID ISpEventMessage myMsg = new MyBaseMsg(MyMsgType.SimpleMsg, MyMsgId.Stop); myMsg.Uid = msg.Uid; return(myMsg); default: break; } //// Do not know which state this is except it is the current state if (msg.EventId == SpConverter.EnumToInt(MyMsgId.Abort)) { //this.GetCurrentState(). // get the GUID ISpEventMessage myMsg = new MyBaseMsg(MyMsgType.SimpleMsg, MyMsgId.Start); // Try recursion - no will not work //this.OnTick(myMsg); //this.GetCurrentState(). //return this.GetOnResultTransition(myMsg); } return(base.OnRuntimeTransitionRequest(msg)); }
public ISpEventMessage GetResponse(ISpEventMessage msg, ISpEventMessage registeredMsg) { return this.GetMsg(msg, () => { return this.provider.Response(msg, registeredMsg); }); }
/// <summary> /// Add an event to the child implementation /// </summary> /// <param name="eventObject">The event object to add</param> protected abstract void AddEvent(ISpEventMessage eventObject);
/// <summary> /// Post an ISpMessage response to an ISpMessage. This will raise the /// ResponseReceived event /// </summary> /// <param name="msg">The reponse to post</param> public void PostResponse(ISpEventMessage msg) { WrapErr.ChkDisposed(this.disposed, 50033); this.RaiseEvent(this.ResponseReceived, msg, "Response"); }
/// <summary> /// Get a clone of the transition object from the store or null if not found /// </summary> /// <param name="store">The store to search</param> /// <param name="eventMsg">The message to insert in the transition object</param> /// <returns>The transition object from the store or null if not found</returns> public static ISpStateTransition GetTransitionCloneFromStore(Dictionary <int, ISpStateTransition> store, ISpEventMessage eventMsg) { WrapErr.ChkParam(store, "store", 51009); WrapErr.ChkParam(eventMsg, "eventMsg", 51010); return(WrapErr.ToErrorReportException(51011, () => { if (store.Keys.Contains(eventMsg.EventId)) { // Clone Transition object from store since its pointers get reset later ISpStateTransition tr = (ISpStateTransition)store[eventMsg.EventId].Clone(); if (tr.ReturnMessage == null) { tr.ReturnMessage = eventMsg; } else { //Log.Info("SpTools", "GetTransitionCloneFromStore", "Found a transition AND - Held msg - transfering GUID"); } // TODO - Look at transfering the GUID here tr.ReturnMessage.Uid = eventMsg.Uid; //tr.ReturnMessage = eventMsg; return tr; } return null; })); }
/// <summary> /// Constructor /// </summary> /// <param name="defaultTick"> /// The default tick event if to provide if there are no queued event objects /// </param> public BaseEventStore(ISpEventMessage defaultTick) { WrapErr.ChkParam(defaultTick, "defaultTick", 50110); this.defaultTick = defaultTick; }
/// <summary> /// Add an event to the queue /// </summary> /// <param name="msg">The message to add</param> protected override void AddEvent(ISpEventMessage msg) { this.queue.Enqueue(msg); }
/// <summary> /// Constructor /// </summary> /// <param name="msg">The paired incoming message</param> public MySimpleOkResponse(ISpEventMessage msg) : this(msg, "") { }
/// <summary> /// Event from the event listner gets stuffed in the store /// </summary> /// <param name="eventObject"></param> void eventListner_MsgReceived(ISpEventMessage eventObject) { this.msgStore.Add(eventObject); this.eventBehavior.EventReceived(BehaviorResponseEventType.MsgArrived); }
/// <summary> /// Constructor /// </summary> /// <param name="defaultTick"> /// The default tick event if to provide if there are no queued event objects /// </param> public PriorityEventStore(ISpEventMessage defaultTick) : base(defaultTick) { }
private void ValidateReturn(ISpEventMessage msg, ISpEventMessage ret) { Assert.AreEqual(msg.Uid, ret.Uid, "Mismatch in GUIDs on return"); }
/// <summary> /// Post an ISpMessage to those listening. This will raise the /// MsgReceived event /// </summary> /// <param name="msg">The message to post</param> public void PostMessage(ISpEventMessage msg) { WrapErr.ChkDisposed(this.disposed, 50032); this.RaiseEvent(this.MsgReceived, msg, "Message"); }
public ISpEventMessage Response(ISpEventMessage msg) { MyEventType eventType = SpConverter.IntToEnum<MyEventType>(msg.EventId); MyMsgType msgType = SpConverter.IntToEnum<MyMsgType>(msg.TypeId); // All my messages are Simple Types so I do not need any other info for types. Otherwise I would need a switch return new MyBaseMsg(msgType, eventType, msg.Priority) { ReturnCode = msg.ReturnCode, StringPayload = msg.StringPayload, ReturnStatus = msg.ReturnStatus }; }
protected override ISpEventMessage ExecOnEntry(ISpEventMessage msg) { Log.Info(this.className, "ExecOnEntry", this.FullName); //return base.ExecOnEntry(msg); return this.MsgFactory.GetDefaultResponse(msg); }
private void TickAndValidateState(ISpEventMessage msg, ISpStateMachine sm, string expected) { ISpEventMessage ret = this.Tick(msg, sm); Thread.Sleep(0); this.ValidateState(sm, expected); this.ValidateReturn(msg, ret); }
/// <summary> /// Constructor /// </summary> /// <param name="type">The transition type</param> /// <param name="nextState">The next state for next state transitions</param> /// <param name="returnMsg">The repsponse to return to the caller</param> public SpStateTransition(SpStateTransitionType type, ISpState nextState, ISpEventMessage returnMsg) { this.type = type; this.nextState = nextState; this.returnMsg = returnMsg; }
private void MsgEqual(ISpEventMessage expected, ISpEventMessage actual) { Assert.IsNotNull(actual, "Current message null"); Assert.AreEqual(expected.EventId, actual.EventId, "Event Id Mismatch"); Assert.AreEqual(expected.Priority, actual.Priority, "Priority Id Mismatch"); Assert.AreEqual(expected.TypeId, actual.TypeId, "Type Id Mismatch"); }
/// <summary> /// Wrapper to retrieve OnResult Transition Object /// </summary> /// <param name="eventMsg">The incomming event message</param> /// <returns>The transition if present, otherwise null</returns> protected ISpStateTransition GetOnResultTransition(ISpEventMessage eventMsg) { return(this.GetTransitionFromStore(this.onResultTransitions, eventMsg)); }
/// <summary> /// Base response type for strong type check on enums /// </summary> /// <param name="msgType">The return message type</param> /// <param name="msg"> /// The paired msg for this response which transmits the UID for correlation /// </param> /// <param name="code">The return code</param> /// <param name="status">The return string</param> public MyBaseResponse(MyMsgType msgType, ISpEventMessage msg, MyReturnCode code, string status) : base(new SpEnumToInt(msgType), msg, new SpEnumToInt(code), status) { }
/// <summary> /// Get the transition object from the store or null if not found /// </summary> /// <param name="store">The store to search</param> /// <param name="eventMsg">The message to insert in the transition object</param> /// <returns>The transition object from the store or null if not found</returns> private ISpStateTransition GetTransitionFromStore(Dictionary <int, ISpStateTransition> store, ISpEventMessage eventMsg) { return(WrapErr.ToErrorReportException(50204, () => { ISpStateTransition t = SpTools.GetTransitionCloneFromStore(store, eventMsg); if (t != null) { this.LogTransition(t, eventMsg); } return t; })); }
/// <summary> /// Virtual method invoked on every tick after. If not overriden it /// will return the default return event message /// </summary> /// <param name="eventMsg">The incoming message</param> /// <returns>A transition object</returns> protected virtual ISpEventMessage ExecOnTick(ISpEventMessage eventMsg) { return(this.MsgFactory.GetDefaultResponse(eventMsg)); }
/// <summary> /// Raise an event in a thread pool if there are subscribers to the event /// </summary> /// <param name="action">The action to raise</param> /// <param name="msg">The message or response to push</param> /// <param name="type">Either message or response identifier string</param> private void RaiseEvent(Action<ISpEventMessage> action, ISpEventMessage msg, string type) { Log.Info("SimpleEventListner", "RaiseEvent", String.Format("Raising Event:{0} type:{1} Event Id:{2}", type, msg.TypeId, msg.EventId)); if (action != null) { ThreadPool.QueueUserWorkItem((threadContext) => { WrapErr.ToErrReport(50030, () => { return String.Format("Unexpected Error Raising Event '{0}'", type); }, () => { // Check again just before execution if (action != null) { action.Invoke(msg); } else { Log.Warning(50031, String.Format("No subscribers to '{0}' message", type)); } }); }); } else { Log.Warning(50031, String.Format("No subscribers to '{0}' message", type)); } }
/// <summary> /// Verifies transitions in order of onEvent, onResult and if not found will return the /// default transition /// </summary> /// <param name="stateFunc"> /// The function that is invoked that will return return message from the state processing /// and use it to check against the onResult queue. /// </param> /// <param name="eventMsg">The incoming message to validate against the onEvent list</param> /// <returns>The OnEvent, OnResult or default transition</returns> private ISpStateTransition GetTransition(bool onEntry, Func <ISpEventMessage, ISpEventMessage> stateFunc, ISpEventMessage msg) { return(WrapErr.ToErrorReportException(9999, () => { // Query the OnEvent queue for a transition BEFORE calling state function (OnEntry, OnTick) ISpStateTransition tr = this.GetOnEventTransition(msg); if (tr != null) { tr.ReturnMessage = (tr.ReturnMessage == null) ? this.MsgFactory.GetResponse(msg) : this.MsgFactory.GetResponse(tr.ReturnMessage); return tr; } // Only considered entered if you do not encounter a preemptive OnEvent transition on entry. In this way // you could get a situation where you cascade down several state depths based on higher up events if (onEntry) { this.isEntered = true; } // Get the transition object from the 'OnResult' queue if ((tr = this.GetOnResultTransition(stateFunc.Invoke(msg))) != null) { tr.ReturnMessage = this.MsgFactory.GetResponse(msg, tr.ReturnMessage); return tr; } // If no transitions registered return SameState with default success message return new SpStateTransition(SpStateTransitionType.SameState, null, this.MsgFactory.GetDefaultResponse(msg)); })); }
protected override ISpEventMessage ExecOnEntry(ISpEventMessage msg) { Log.Info(this.className, "ExecOnEntry", ""); return base.ExecOnEntry(msg); }
/// <summary> /// Constructor /// </summary> /// <param name="defaultTick"> /// The default tick event if to provide if there are no queued event objects /// </param> public SimpleDequeEventStore(ISpEventMessage defaultTick) : base(defaultTick) { }
private ISpEventMessage Tick(ISpEventMessage msg, ISpStateMachine sm) { ISpEventMessage ret = null; TestHelpers.CatchUnexpected(() => { ret = sm.Tick(msg); }); return ret; }
/// <summary> /// This will return the default success response with only the GUID /// transfered from the incoming message to satisfy any need of msg /// correlation /// </summary> /// <param name="msg">The message received by the state machine</param> /// <returns>The default response message</returns> public ISpEventMessage GetDefaultResponse(ISpEventMessage msg) { return this.GetMsg(msg, () => { return this.provider.DefaultMsg(msg); }); }
/// <summary>Base response type for strong type check on enumssummary> /// <param name="msgType">The return message type</param> /// <param name="msg">Paired msg for this response which transmits the UID for correlation</param> /// <param name="code">The return code</param> /// <param name="status">The return string</param> public MyBaseResponse(MyMsgType msgType, ISpEventMessage msg, MyReturnCode code, string status) : base(msgType, msg, code, status) { }
public void SendMsg(ISpEventMessage msg) { DummyDI.EventListnerInstance.PostMessage(msg); }
public ISpEventMessage DefaultMsg(ISpEventMessage msg) { return new MySimpleOkResponse(msg); }