Example #1
0
        void HandleTaskResult(Task <object> t, WorkableTask task, WorkableLogger tasklogger)
        {
            tasklogger.LogPerformance();
            if (t.IsCanceled)
            {
                tasklogger.Warning("Workflow execution was aborted");
                task.Status = TaskStatus.Canceled;
            }
            else if (t.IsFaulted)
            {
                tasklogger.Error("Workflow failed to execute", t.Exception?.InnerException ?? t.Exception);
                task.Status = TaskStatus.Failure;
            }
            else
            {
                if (t.Result is SuspendState state)
                {
                    tasklogger.Info($"Workflow was suspended at '{state}'");
                    task.SuspensionState = state;
                    task.Status          = TaskStatus.Suspended;

                    // don't finish task when it gets suspended
                    // else it would get serialized and suspension state is lost
                    // TODO: this could get refactored to allow for state serialization
                    return;
                }

                task.Result = t.Result;
                tasklogger.Info($"Workflow executed successfully with result '{task.Result}'");
                task.Status = TaskStatus.Success;
            }

            task.Finished = DateTime.Now;
            taskservice.FinishTask(task.Id).GetAwaiter().GetResult();
        }
        async Task <WorkableTask> Execute(IScript scriptinstance, WorkableTask scripttask, IDictionary <string, object> variables, TimeSpan?wait)
        {
            WorkableLogger scriptlogger = new WorkableLogger(logger, scripttask);

            scripttask.Task = Execute(scriptinstance, scriptlogger, variables, scripttask.Token.Token).ContinueWith(t => {
                if (t.IsCanceled)
                {
                    scriptlogger.Warning("Script execution was aborted");
                    scripttask.Status = TaskStatus.Canceled;
                }
                else if (t.IsFaulted)
                {
                    scriptlogger.Error("Script failed to execute", t.Exception?.InnerException ?? t.Exception);
                    scripttask.Status = TaskStatus.Failure;
                }
                else
                {
                    scripttask.Result = t.Result;
                    scriptlogger.Info($"Script executed successfully with result '{scripttask.Result}'");
                    scripttask.Status = TaskStatus.Success;
                }

                scripttask.Finished = DateTime.Now;
                scriptinstances.FinishTask(scripttask.Id).GetAwaiter().GetResult();
            });

            if (wait.HasValue && !scripttask.Task.IsCompleted)
            {
                await Task.WhenAny(scripttask.Task, Task.Delay(wait.Value));
            }

            return(scripttask);
        }
Example #3
0
        async Task <InstanceTransition> EvaluateTransitions(IInstanceNode current, WorkableLogger tasklogger, IVariableProvider variableprovider, List <InstanceTransition> transitions, CancellationToken token)
        {
            if (transitions == null)
            {
                return(null);
            }

            InstanceTransition transition = null;

            foreach (InstanceTransition conditionaltransition in transitions.Where(c => c.Condition != null))
            {
                if (await conditionaltransition.Condition.ExecuteAsync <bool>(variableprovider, token))
                {
                    transition = conditionaltransition;
                    break;
                }
            }

            if (transition == null)
            {
                InstanceTransition[] defaulttransitions = transitions.Where(t => t.Condition == null).ToArray();
                if (defaulttransitions.Length > 1)
                {
                    throw new InvalidOperationException($"More than one default transition defined for '{current.NodeName}'.");
                }
                transition = defaulttransitions.FirstOrDefault();
            }

            if (transition?.Log != null)
            {
                try {
                    tasklogger.Info(await transition.Log.ExecuteAsync <string>(variableprovider, token));
                }
                catch (Exception e) {
                    tasklogger.Error($"Error executing transition log of '{current.NodeName}'->'{transition.Target?.NodeName}'", e);
                    throw;
                }
            }
            return(transition);
        }
Example #4
0
        /// <inheritdoc />
        public async Task <WorkableTask> Continue(Guid taskid, IDictionary <string, object> variables = null, TimeSpan?wait = null)
        {
            WorkableTask task = await taskservice.GetTask(taskid);

            if (task.Status != TaskStatus.Suspended)
            {
                throw new ArgumentException($"Task '{taskid}' is not suspended.");
            }
            if (task.SuspensionState == null)
            {
                throw new InvalidOperationException($"Task '{taskid}' has no suspension state linked to it.");
            }

            WorkableLogger tasklogger = new WorkableLogger(logger, task);

            tasklogger.Info("Resuming execution of workflow", string.Join("\n", variables?.Select(p => $"{p.Key}={p.Value}") ?? new string[0]));

            try {
                task.Status = TaskStatus.Running;
                task.Task   = Task.Run(async() => {
                    WorkflowInstanceState workflowstate = new WorkflowInstanceState(task.SuspensionState.Workflow, tasklogger, task.SuspensionState.Variables, GetWorkflowInstance, this, task.SuspensionState.Language, task.SuspensionState.Profiling);
                    return(await ContinueState(task.SuspensionState, workflowstate, tasklogger, variables, task.Token.Token));
                }).ContinueWith(t => HandleTaskResult(t, task, tasklogger));
            }
            catch (Exception e) {
                tasklogger.Error("Failed to execute workflow", e);
                task.Finished = DateTime.Now;
                task.Status   = TaskStatus.Failure;
                await taskservice.FinishTask(task.Id);
            }

            if (wait.HasValue && !task.Task.IsCompleted)
            {
                await Task.WhenAny(task.Task, Task.Delay(wait.Value));
            }

            return(task);
        }