public string ResumeWorkflowAsync_new(WorkflowRun workflowRun, IWorkflowEvent resumeEvent) { Factory.WorkflowRunTaskManager.RegisterStart(workflowRun.TaskId); bool runInForeground = WorkflowRunContext.Current.RunTriggersInCurrentThread; var queueEvent = resumeEvent as IWorkflowQueuedEvent; if (queueEvent == null) { EventLog.Application.WriteError("Attempted to queue a resume task that cannot be queued, running it on the foreground thread instead. EventType: {resumeEvent.GetType()}"); runInForeground = true; } if (runInForeground) { ResumeWorkflow(workflowRun, resumeEvent); } else { var task = ResumeWorkflowHandler.CreateBackgroundTask(workflowRun, queueEvent); Factory.BackgroundTaskManager.EnqueueTask(task); HandleDiagnostics(workflowRun, "Queued"); } return(workflowRun.TaskId); }
public void SuspendRestore() { using (new SecurityBypassContext()) { var handler = new ResumeWorkflowHandler(); var run = new WorkflowRun() { WorkflowRunStatus_Enum = WorkflowRunState_Enumeration.WorkflowRunSuspended }; run.Save(); var task = ResumeWorkflowHandler.CreateBackgroundTask(run, new WorkflowRestoreEvent()); var taskEntity = handler.CreateSuspendedTask(task).As <SuspendedRun>(); taskEntity.Save(); taskEntity.Should().NotBeNull(); taskEntity.SrRun.Should().NotBeNull(); taskEntity.SrRun.Id.Should().Be(run.Id); var bgTasks = handler.RestoreSuspendedTasks(); bgTasks.Should().HaveCount(1); var runParam = bgTasks.First().GetData <ResumeWorkflowParams>(); runParam.WorkflowRunId.ShouldBeEquivalentTo(run.Id); Assert.That(runParam.WorkflowRunId, Is.EqualTo(run.Id)); } }
/// <summary> /// Resume any suspended runs, putting them back on the queue. /// Note that this does not deal with the queue already containing suspended runs. /// </summary> public static void ResumeSuspendedRuns() { var suspendedIds = Entity.GetCalculationMatchesAsIds("Status='Long running'", WorkflowRun.WorkflowRun_Type, false); if (suspendedIds.Any()) { var runs = Entity.Get <WorkflowRun>(suspendedIds); foreach (var run in runs) { var restoreTask = ResumeWorkflowHandler.CreateBackgroundTask(run, new WorkflowRestoreEvent()); Factory.BackgroundTaskManager.EnqueueTask(restoreTask); } } }
void ActionOnTask_new(long runId, UserCompletesTaskEvent resumeEvent, bool runInThread) { BackgroundTask bgTask; using (new SecurityBypassContext()) { var run = Entity.Get <WorkflowRun>(runId); // If we don't do this we get caching problems var wf = run.WorkflowBeingRun; bgTask = ResumeWorkflowHandler.CreateBackgroundTask(run, resumeEvent); } if (runInThread) { Factory.BackgroundTaskManager.ExecuteImmediately(bgTask); } else { Factory.BackgroundTaskManager.EnqueueTask(bgTask); } }
private WorkflowRun FinalizeRun(IRunState runState) { WorkflowRun run; using (Profiler.Measure("WorkflowRunner.Instance.FinalizeRun")) { using (new SecurityBypassContext()) { try { run = runState.WorkflowRun; runState.CompletedAt = DateTime.UtcNow; if (!run.IsTemporaryId) { run = Entity.Get <WorkflowRun>(runState.WorkflowRun, true, WorkflowRun.WorkflowRunExitPoint_Field, WorkflowRun.HasTimeout_Field, WorkflowRun.PendingActivity_Field, WorkflowRun.RunStepCounter_Field, WorkflowRun.WorkflowRunStatus_Field, WorkflowRun.RunCompletedAt_Field, WorkflowRun.StateInfo_Field); } var deferredRun = run as WorkflowRunDeferred; if (deferredRun != null) { deferredRun.Sync(); } runState.SyncToRun(run); WorkflowRunContext.Current.DeferSave(run); // // Raise a completed child event // if (run != null && run.ParentRun != null && IsRunCompleted(run)) { // This should be hooked into an eventing system. As we don't have one, just run the resume async. runState.WorkflowInvoker.PostEvent(new ChildWorkflowCompletedEvent(run)); } // // Add a restore message to the queue if we are suspended // if (run != null && run.WorkflowRunStatus_Enum == WorkflowRunState_Enumeration.WorkflowRunSuspended) { WorkflowRunContext.Current.DeferAction(() => { // This should be hooked into an eventing system. As we don't have one, just run the resume async. var restoreTask = ResumeWorkflowHandler.CreateBackgroundTask(run, new WorkflowRestoreEvent()); Factory.BackgroundTaskManager.EnqueueTask(restoreTask); }); } // // Let the world know we have finished WorkflowRunContext.Current.DeferAction(() => { if (run.WorkflowRunStatus_Enum == WorkflowRunState_Enumeration.WorkflowRunPaused || run.WorkflowRunStatus_Enum == WorkflowRunState_Enumeration.WorkflowRunCompleted || run.WorkflowRunStatus_Enum == WorkflowRunState_Enumeration.WorkflowRunFailed) { Factory.WorkflowRunTaskManager.RegisterComplete(run.TaskId, run.Id.ToString(CultureInfo.InvariantCulture)); } else { Factory.WorkflowRunTaskManager.SetResult(run.TaskId, run.Id.ToString(CultureInfo.InvariantCulture)); } HandleDiagnostics(run, run.WorkflowRunStatus_Enum.ToString()); }); } catch (Exception ex) { Workflow workflow = runState != null?Entity.Get <Workflow>(runState.WorkflowRunId) : null; var msg = string.Format("Workflow: {0}. Unexpected error when finalizing the workflow run ({1}), version ({2}).", runState != null ? runState.GetSafeWorkflowDescription() : "", runState != null ? runState.WorkflowRunId : -1L, workflow != null ? workflow.WorkflowVersion : 0); var log = msg + Environment.NewLine + ex.Message; #if DEBUG log += Environment.NewLine + ex.StackTrace; #endif EventLog.Application.WriteError(log); throw new Exception(msg, ex); } } } return(run); }