/// <summary> /// Used to get the event out of the node. /// </summary> /// <param name="actionNode">The action node to process.</param> /// <returns></returns> public bool Next(out EventActionNodePersist <TKey, TState, TEvent, TParam, TCtx, TUserId> actionNode) { if (Interlocked.CompareExchange( ref this.currentRunningState, RUNNING, IDLE) == IDLE) { if (this.skipQueue.Next(out actionNode)) { this.currentEventNode = actionNode; return(true); } Volatile.Write(ref this.currentRunningState, IDLE); return(false); } else if (Interlocked.CompareExchange( ref this.currentRunningState, RUNNING, RETRY) == RETRY) { actionNode = this.retryEvent; this.currentEventNode = this.retryEvent; this.retryEvent = null; return(true); } actionNode = null; return(false); }
/// <summary> /// Called when you are done with the event. /// </summary> /// <returns>The task that performs the update.</returns> public async Task DoneWithEvent() { while (true) { try { if (this.currentEventNode == null) { log.Warn($"The current event node is null. This should never happen."); } else { if (!this.currentEventNode.RunOnThread) { await this.eventPersistedStore.SaveResult( this.currentEventNode.Id, EventResultType.Completed); } this.currentEventNode = null; } Volatile.Write(ref this.currentRunningState, IDLE); break; } catch (Exception ex) { log.Error(ex, ex.Message); Thread.Sleep(5); } } }
public void RetryEvent( EventActionNodePersist <TKey, TState, TEvent, TParam, TCtx, TUserId> eventActionNodePersist) { Interlocked.Increment(ref this.retryCount); Volatile.Write(ref this.retryEvent, eventActionNodePersist); this.currentEventNode = null; // TODO add a delay. Will need to use either a retry data structure or just use a timer but there is a limit to the amount of timers. this.retryService.Retry(new TimeSpan(0, 0, this.CalculateDelay()), () => { this.newEventSubject.Next(); }); }
public bool Skip(EventActionNodePersist <TKey, TState, TEvent, TParam, TCtx, TUserId> actionNode) { var added = this.skipQueue.AddDefer(actionNode); // Need to do this here since skip is a special event. Volatile.Write(ref this.currentRunningState, IDLE); if (!added) { this.eventPersistedStore.SaveResult(actionNode.Id, EventResultType.Full); log.Warn($"Skip queue is full. State machine id {actionNode.StateMachineKey} {actionNode.Id}"); } return(added); }
public async Task <bool> Add(EventActionNodePersist <TKey, TState, TEvent, TParam, TCtx, TUserId> actionNode) { try { if (actionNode.RunOnThread) { var result = this.skipQueue.Add(actionNode); await this.newEventReceived.NewEvent((TCtx)this); return(result); } else { await this.eventPersistedStore.Save(actionNode); var able = this.skipQueue.Add(actionNode); if (able) { await this.newEventReceived.NewEvent((TCtx)this); return(true); } else { await this.eventPersistedStore.SaveResult(actionNode.Id, EventResultType.Full); return(false); } } } catch (Exception ex) { log.Error(ex, ex.Message); // TODO Come up with a retry idea but ordering is important so this could be difficult. return(false); } }