Esempio n. 1
0
        /// <summary>
        /// Start a workflow and and wait for it to complete or pause.
        /// </summary>
        /// <returns></returns>
        public WorkflowRun RunWorkflow(WorkflowStartEvent startEvent)
        {
            if (startEvent.Workflow == null)
            {
                throw new ArgumentException($"{nameof(startEvent)} missing mandatory field Workflow.");
            }

            // deny workflow run when tenant is disabled
            if (TenantHelper.IsDisabled())
            {
                EventLog.Application.WriteWarning("Workflow run denied, tenant is disabled. \"{0\"({1})", startEvent.Workflow.Name, startEvent.Workflow.Id);
                return(null);
            }

            using (Profiler.Measure("WorkflowRunner.Instance.RunWorkflow"))
            {
                using (new SecurityBypassContext())
                {
                    if (startEvent.Workflow.WfNewerVersion != null)
                    {
                        throw new ArgumentException("Attempted to run a workflow that is not the newest version.");
                    }


                    // create a wf run then pass into the workflow
                    var run = new WorkflowRunDeferred(startEvent.Workflow, startEvent.Trigger)
                    {
                        RunTrace  = startEvent.Trace,
                        ParentRun = startEvent.ParentRun
                    };

                    return(ProcessWorkflowInContext(run, startEvent));
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Raise an event. Events are handled in the order raised after the other processing has completed
        /// </summary>
        /// <param name="nextEvent"></param>
        public void PostEvent(IWorkflowEvent nextEvent)
        {
            Action action = null;

            var asChildRunStart = nextEvent as ChildWorkflowStartEvent;

            if (asChildRunStart != null)
            {
                var parentRun = asChildRunStart.ParentRun;
                if (parentRun != null)
                {
                    var triggerDepth = WorkflowRunContext.Current.TriggerDepth;
                    action = () => {
                        // Need to handle deferred here otherwise "double-resume" fails (BUG #27863)
                        using (new WorkflowRunContext(true)
                        {
                            TriggerDepth = triggerDepth + 1
                        })
                        {
                            var startEvent = new WorkflowStartEvent(asChildRunStart.WorkflowToStart)
                            {
                                Arguments = asChildRunStart.Inputs,
                                ParentRun = parentRun,
                                Trace     = parentRun.RunTrace ?? false
                            };

                            // TODO: Change this into a call into the BackgroundTaskManager
                            WorkflowRunner.Instance.RunWorkflow(startEvent);
                        }
                    };
                }
            }
            else
            {
                var asChildRunCompleted = nextEvent as ChildWorkflowCompletedEvent;

                if (asChildRunCompleted != null)
                {
                    var completedRun = asChildRunCompleted.CompletedRun;
                    if (completedRun != null)
                    {
                        // Need to decrement the trigger depth otherwise "child workflow in a foreach" fails (BUG #27863)
                        if (WorkflowRunContext.Current.TriggerDepth > 0)
                        {
                            WorkflowRunContext.Current.TriggerDepth--;
                        }
                        action = () => WorkflowRunner.Instance.ResumeWorkflow(completedRun.ParentRun, asChildRunCompleted);
                    }
                }
            }

            if (action != null)
            {
                // NOTE: runBeforeSave was passed as "true" here, however, this led to issues where previously
                // unsaved copies of the same run were already present in the queue, causing endless looping (BUG #27863)
                WorkflowRunContext.Current.DeferAction(action, false);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Factory to create a workflow run , the workflow starts async
        /// </summary>
        /// <param name="workflowToRun"></param>
        /// <param name="args"></param>
        /// <param name="trace"></param>
        /// <param name="invoker"></param>
        /// <returns>The workflow run task ID</returns>
        public string RunWorkflowAsync(WorkflowStartEvent startEvent)
        {
            if (startEvent == null)
            {
                throw new ArgumentNullException(nameof(startEvent));
            }

            if (startEvent.Workflow == null)
            {
                throw new ArgumentException("Missing mandatory argument workflow to on WorkflowStartEvent.");
            }

            using (Profiler.Measure("WorkflowRunner.Instance.StartWorkflowAsync"))
            {
                using (new SecurityBypassContext())
                {
                    if (startEvent.Workflow.WfNewerVersion != null)
                    {
                        throw new ArgumentException("Attempted to run a workflow that is not the newest version.");
                    }
                }

                // create a wf run then pass into the workflow
                var run = new WorkflowRunDeferred(startEvent.Workflow)
                {
                    RunTrace = startEvent.Trace
                };

                var stopWatch = new Stopwatch();
                stopWatch.Start();

                Factory.WorkflowRunTaskManager.RegisterStart(run.TaskId);

                HandleDiagnostics(run, WorkflowRunState_Enumeration.WorkflowRunStarted.ToString( ));

                WorkflowRunContext.Current.QueueAction(() =>
                {
                    stopWatch.Stop();

                    perfCounters.GetPerformanceCounter <AverageTimer32PerformanceCounter>(WorkflowPerformanceCounters.QueueDurationCounterName).AddTiming(stopWatch);

                    using (new WorkflowRunContext(true)
                    {
                        RunTriggersInCurrentThread = true
                    })                                                                         // need to ensure that all deferred saves occur before we register complete.
                    {
                        ProcessWorkflowInContext(run, startEvent);
                    }
                });

                return(run.TaskId);
            }
        }
        private void ConvertFromXMLForEvents(WorkflowProcess process, XElement element)
        {
            // Get list Events
            IEnumerable <XElement> EventsList = element.Descendants(XMLNodeName.startEvent.ToString());

            foreach (XElement xEvent in EventsList)
            {
                WorkflowStartEvent Event = _workflowStartEventConvertor.ConvertFromString(xEvent.ToString());
                process.AddEvent(Event);
            }

            EventsList = element.Descendants(XMLNodeName.endEvent.ToString());
            foreach (XElement xEvent in EventsList)
            {
                WorkflowEndEvent Event = _workflowEndEventConvertor.ConvertFromString(xEvent.ToString());
                process.AddEvent(Event);
            }

            EventsList = element.Descendants(XMLNodeName.intermediateThrowEvent.ToString());
            foreach (XElement xEvent in EventsList)
            {
                WorkflowIntermediateThrowEvent Event = _workflowIntermediateThrowEventConvertor.ConvertFromString(xEvent.ToString());
                process.AddEvent(Event);
            }

            EventsList = element.Descendants(XMLNodeName.intermediateCatchEvent.ToString());
            foreach (XElement xEvent in EventsList)
            {
                WorkflowIntermediateCatchEvent Event = _workflowIntermediateCatchEventConvertor.ConvertFromString(xEvent.ToString());
                process.AddEvent(Event);
            }

            EventsList = element.Descendants(XMLNodeName.boundaryEvent.ToString());
            foreach (XElement xEvent in EventsList)
            {
                WorkflowBoundaryEvent Event = _workflowBoundaryEventConvertor.ConvertFromString(xEvent.ToString());
                process.AddEvent(Event);
            }
        }
Esempio n. 5
0
 public string RunWorkflowAsync(WorkflowStartEvent startEvent)
 {
     return(StartWorkflowAsyncFn(startEvent));
 }
Esempio n. 6
0
 public WorkflowRun RunWorkflow(WorkflowStartEvent startEvent)
 {
     throw new NotImplementedException();
 }