/// <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)); } } }
/// <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); } }
/// <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); } }
public string RunWorkflowAsync(WorkflowStartEvent startEvent) { return(StartWorkflowAsyncFn(startEvent)); }
public WorkflowRun RunWorkflow(WorkflowStartEvent startEvent) { throw new NotImplementedException(); }