public WfResult Run(CancellationToken extToken) { _logger.Information("Start Processing Workflow Constraint {ItemKey}", _item.Key); WfResult result = WfResult.Unknown; WorkflowAttributeCollection attributes = _db.WorkflowAttributeCollectionGet(_item.WorkflowId, _item.StepId, _item.ConstId, _item.RunId); attributes.Merge(_wfp.Attributes); WorkflowActivity activity = new WorkflowActivity(_item.Process, attributes, _logger); TimeSpan timeout = TimeSpan.FromSeconds((_item.WaitPeriod <= 0) ? 7200 : _item.WaitPeriod); TimeSpan sleep = TimeSpan.FromSeconds((_item.Ping <= 0) ? 30 : _item.Ping); try { using (CancellationTokenSource timeoutCts = new CancellationTokenSource(timeout)) using (CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(extToken, timeoutCts.Token)) { Task <WfResult> task = Task.Factory.StartNew(() => { WfResult const_result = WfResult.Unknown; IWorkflowActivity runner = activity.Activate(); while (true) { //Run constraint activity using (linkedCts.Token.Register(Thread.CurrentThread.Abort)) { try { //do thread hard abort if it is stuck on Run //constraint logic should never allow this to happen thou const_result = runner.Run(linkedCts.Token); _logger.Debug("Constraint {ItemKey} current status = {WfStatus}", _item.Key, const_result.StatusCode.ToString()); if (const_result.StatusCode != WfStatus.Waiting) { break; } } catch (ThreadAbortException ex) { throw ex; } } //cts.Token.ThrowIfCancellationRequested(); Task.Delay(sleep, linkedCts.Token).Wait(); if (linkedCts.IsCancellationRequested) { const_result = WfResult.Canceled; break; } } return(const_result); }, linkedCts.Token); result = task.Result; } } catch (AggregateException ex) { //result = WfResult.Create(WfStatus.Failed,"timeout",-3); throw ex; } finally { _logger.Information("Finish Processing Workflow Constraint {ItemKey} with result - {WfStatus}", _item.Key, result.StatusCode.ToString()); } return(result); }
public WfResult Run(CancellationToken extToken) { _logger.Information("Start Processing Workflow step {ItemKey}:{ItemName}", _step.Key, _step.StepName); WfResult result = WfResult.Succeeded; try { //Step Constraints if (_step.StepConstraints != null) { foreach (WorkflowConstraint wfc in _step.StepConstraints) { if (wfc.IsDisabled || wfc.Process.ProcessId == 0) { _logger.Debug("Constraint process is not defined or disabled {ItemKey}:{ItemName}", _step.Key, _step.StepName); continue; } if ((wfc.Process.ScopeId & 12) == 0) { throw new ArgumentException(String.Format("Constraint Process is not of correct scope 0011 = {0}", wfc.Process.ScopeId)); } wfc.WorkflowId = _step.WorkflowId; wfc.StepId = _step.StepId; wfc.RunId = _step.RunId; WorkflowConstraintProcessor wcp = new WorkflowConstraintProcessor(wfc, _wfp); result = wcp.Run(extToken); if (result.StatusCode == WfStatus.Failed) { _logger.Error("Workflow step {ItemKey}:{ItemName} failed with: {ErrorCode}", _step.Key, _step.StepName, result.Message, result.ErrorCode); return(result); } } } WorkflowAttributeCollection attributes = null; if (_step.StepProcess != null) { //always evaluate step attributes attributes = _db.WorkflowAttributeCollectionGet(_step.WorkflowId, _step.StepId, 0, _step.RunId); attributes.Merge(_wfp.Attributes); if (_step.StepProcess.ProcessId != 0) { if ((_step.StepProcess.ScopeId & 3) == 0) { throw new ArgumentException(String.Format("Step Process is not of correct scope 1100 = {0}", _step.StepProcess.ScopeId)); } //Run Step Activity here WorkflowActivity step_activity = new WorkflowActivity(_step.StepProcess, attributes, _logger); IWorkflowActivity step_runner = step_activity.Activate(); result = (ProcessRunAsync(step_runner, extToken, _step.StepRetry, _step.StepDelayOnRetry, _step.StepTimeout, _logger)).Result; } else { _logger.Debug("Step process is not defined. Skipped {ItemKey}", _step.Key); } } if (result.StatusCode == WfStatus.Succeeded && _step.StepOnSuccessProcess != null) { _logger.Information("On step success"); _logger.Debug("On success process - {ProcessName}", _step.StepOnSuccessProcess.Process); if ((_step.StepOnSuccessProcess.ScopeId & 3) == 0) { throw new ArgumentException(String.Format("OnSuccess Process is not of correct scope 1100 = {0}", _step.StepOnSuccessProcess.ScopeId)); } //Run OnSuccess Activity here //re-evaluate attribites //if (attributes == null) attributes = _db.WorkflowAttributeCollectionGet(_step.WorkflowId, _step.StepId, 0, _step.RunId); WorkflowActivity success_activity = new WorkflowActivity(_step.StepOnSuccessProcess, attributes, _logger); IWorkflowActivity success_runner = success_activity.Activate(); WfResult task_result = (ProcessRunAsync(success_runner, extToken, 0, 0, _step.StepTimeout, _logger)).Result; if (task_result.StatusCode == WfStatus.Failed) { result = task_result; } } else if (result.StatusCode == WfStatus.Failed && _step.StepOnFailureProcess != null) { _logger.Information("On step failure"); _logger.Debug("On failure process - {ProcessName}", _step.StepOnFailureProcess.Process); if ((_step.StepOnFailureProcess.ScopeId & 3) == 0) { throw new ArgumentException(String.Format("OnFailure Process is not of correct scope 1100 = {0}", _step.StepOnFailureProcess.ScopeId)); } //Run OnFailure Activity here //re-evaluate attribites //if (attributes == null) attributes = _db.WorkflowAttributeCollectionGet(_step.WorkflowId, _step.StepId, 0, _step.RunId); WorkflowActivity failure_activity = new WorkflowActivity(_step.StepOnFailureProcess, attributes, _logger); IWorkflowActivity failure_runner = failure_activity.Activate(); WfResult task_result = (ProcessRunAsync(failure_runner, extToken, 0, 0, _step.StepTimeout, _logger)).Result; if (task_result.StatusCode == WfStatus.Failed) { result = task_result; } } } catch (AggregateException aex) { _logger.Error(aex, "AggregateException: {Message}", aex.Message); foreach (var ex in aex.InnerExceptions) { _logger.Error(ex, "InnerException: {Message}", ex.Message); } result = WfResult.Create(WfStatus.Failed, aex.Message, -10); } catch (Exception ex) { _logger.Error(ex, "Exception: {0}", ex.Message); result = WfResult.Create(WfStatus.Failed, ex.Message, -10); } _logger.Information("Workflow step {ItemKey}:{ItemName} finished with result {WfStatus}", _step.Key, _step.StepName, result.StatusCode.ToString()); return(result); }