public WorkflowActivity(WorkflowProcess process, WorkflowAttributeCollection attributes, ILogger logger)
        {
            _process = process;
            _logger  = logger;

            _attributes.Merge(attributes);
        }
        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);
        }
Example #3
0
        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);
        }