Exemple #1
0
        public static async Task <JToken> ExecuteAsync(this SendEventAction action,
                                                       StateMachineContext context,
                                                       JToken input)
        {
            action.CheckArgNull(nameof(action));
            context.CheckArgNull(nameof(context));
            input.CheckArgNull(nameof(input));

            var eventDefinition = context.Workflow.Events.SingleOrDefault(ev => ev.Name.IsEqualTo(action.Event));

            if (eventDefinition == null)
            {
                throw new InvalidOperationException("Unable to resolve event definition: " + action.Event);
            }

            JToken payload = action.Expression?.EvalExpr(input, context) ?? new JObject();

            var evt = context.Host.CreateEventInstance(eventDefinition.Name,
                                                       eventDefinition.Type,
                                                       eventDefinition.Source,
                                                       payload,
                                                       action.ContextAttributes);

            Debug.Assert(evt != null);

            await context.Host.SendEventsAsync(new[] { evt }, context.CancelToken);

            return(JValue.CreateNull());
        }
Exemple #2
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;
                }
            }
        }