private async Task ProcessTransition(StateTransition <TActor, TStatus> transition) { var dispatched = false; try { CancellationToken.ThrowIfCancellationRequested(); // Capture status value before executng the transition TStatus prevStatus = transition.Source.Status; var newStatus = await transition.ExecuteAsync(); await ChangeStatus(transition.Source, newStatus); if (transition.Source.Status.Equals(prevStatus)) { Logger.LogWarning("Status did not change during transition - possible logical error (status = {status}).", prevStatus); } // Place the actor to dispatcher queue _dispatcher.Post(transition.Source); dispatched = true; } catch (OperationCanceledException) { // Operation has been cancelled, simply drop the item // Since the state did not change the item will be picked up again from the queue } catch (StateMachineException ex) { // Process terminated due to internal issues, log message and drop the item // Since the state did not change the item will be picked up again from the queue Logger.LogError(ex, ex.Message); } catch (StateTransitionException ex) { await SetErrorStatus(transition.Source, (TStatus)ex.ErrorStatus, ex.Message, ex.InnerException); } catch (Exception ex) { await SetErrorStatus(transition.Source, transition.ErrorStatus, ex.Message, ex); } finally { if (!dispatched) { _countdown.Release(); } } }
private void DispatchActor(TActor actor) { StateTransition <TActor, TStatus> transition = null; try { transition = GetNextTransition(actor); } catch (Exception ex) { Logger.LogError(ex, "Error while getting next transition."); } if (transition != null && transition.Source != null) { _processor.Post(transition); } else { // No more tranistions found for this actor we should signal completion. _countdown.Release(); } }