コード例 #1
0
        private static async Task <JToken> EnterState(State state, StateMachineContext context)
        {
            Debug.Assert(state != null);
            Debug.Assert(context != null);

            await context.RecordObservableActionAsync(ObservableAction.EnterState,
                                                      () => new Dictionary <string, object>
            {
                { "stateName", state.Name }
            });

            var data = state.InputFilter?.EvalExpr(context.Data, context) ?? context.Data;

            Debug.Assert(data != null);

            if (state.EnterAction != null)
            {
                var result = await state.EnterAction.ExecuteAsync(context, data);

                Debug.Assert(result != null);

                result.Merge(context.Data, state.EnterResultHandler, context);
            }

            return(data);
        }
コード例 #2
0
        private static async Task ExitState(State state, StateMachineContext context, JToken data)
        {
            Debug.Assert(state != null);
            Debug.Assert(context != null);
            Debug.Assert(data != null);

            if (state.ExitAction != null)
            {
                var result = await state.ExitAction.ExecuteAsync(context, data);

                Debug.Assert(result != null);

                result.Merge(context.Data, state.ExitResultHandler, context);
            }

            await context.RecordObservableActionAsync(ObservableAction.ExitState,
                                                      () => new Dictionary <string, object>
            {
                { "stateName", state.Name }
            });
        }
コード例 #3
0
        public static async Task <JToken> ExecuteAsync(this ModelAction action,
                                                       StateMachineContext context,
                                                       JToken input)
        {
            action.CheckArgNull(nameof(action));
            context.CheckArgNull(nameof(context));
            input.CheckArgNull(nameof(input));

            await context.RecordObservableActionAsync(ObservableAction.BeforeAction,
                                                      () => new Dictionary <string, object>
            {
                { "actionName", action.Name },
                { "actionType", action.GetType().FullName }
            });

            Func <StateMachineContext, JToken, Task <JToken> > executeFunc = action switch
            {
                InjectDataAction inject => inject.ExecuteAsync,
                ParallelAction parallel => parallel.ExecuteAsync,
                SequenceAction sequence => sequence.ExecuteAsync,
                SendEventAction send => send.ExecuteAsync,
                DelayAction delay => delay.ExecuteAsync,
                InvokeSubflowAction subflow => subflow.ExecuteAsync,
                InvokeFunctionAction function => function.ExecuteAsync,
                ForEachAction forEach => forEach.ExecuteAsync,
                                                               _ => throw new NotImplementedException("Action behavior not implemented: " + action.GetType().FullName)
            };

            Debug.Assert(executeFunc != null);

            var            attempts = 0;
            DateTimeOffset?start    = null;

            while (true)
            {
                try
                {
                    var result = await executeFunc(context, input);

                    await context.RecordObservableActionAsync(ObservableAction.AfterAction,
                                                              () => new Dictionary <string, object>
                    {
                        { "actionName", action.Name },
                        { "actionType", action.GetType().FullName }
                    });

                    return(result);
                }
                catch (Exception ex)
                {
                    if (action.TryHandleError(JObject.FromObject(ex),
                                              context,
                                              out RetryPolicy? retryPolicy))
                    {
                        if (retryPolicy == null)
                        {
                            return(JValue.CreateNull());
                        }
                        else
                        {
                            TimeSpan elapsedDelay;

                            if (start == null)
                            {
                                start        = DateTimeOffset.UtcNow;
                                elapsedDelay = TimeSpan.Zero;
                            }
                            else
                            {
                                elapsedDelay = DateTimeOffset.UtcNow.Subtract(start.Value);
                            }

                            var retry = await retryPolicy.ShouldRetryAsync(context, ++attempts, elapsedDelay);

                            if (retry)
                            {
                                continue;
                            }
                        }
                    }

                    throw;
                }
            }
        }