/// <summary>
        /// Cancel the Batch(StepId = 0)/Step on the ExitEvent
        /// </summary>
        /// <param name="WfId"></param>
        /// <param name="StepId"></param>
        /// <param name="RunId"></param>
        /// <param name="LoopGroup"></param>
        public WfResult WorkflowExitEventCheck(int WfId, int StepId, int RunId)
        {
            string cmd_text = String.Format(WORKFLOW_EXIT_EVENT_QUERY,
                                            WfId,
                                            StepId,
                                            RunId);
            var ret = ExecuteScalar(cmd_text);

            if (ret == null)
            {
                return(WfResult.Unknown);
            }

            WfResult result;

            switch (DBStatus.DbValue((short)ret))
            {
            case WfStatus.Unknown:
            case WfStatus.Running:
                result = WfResult.Started;
                break;

            case WfStatus.Failed:
                result = WfResult.Create(WfStatus.Failed, "Canceled", 0);
                break;

            case WfStatus.Succeeded:
                result = WfResult.Create(WfStatus.Succeeded, "Canceled", 0);
                break;

            default:
                result = WfResult.Started;
                break;
            }

            return(result);
        }
Exemplo n.º 2
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);
        }
Exemplo n.º 3
0
        private async Task <WfResult> ProcessRunAsync(IWorkflowActivity runner, CancellationToken token, int retry, int delay, int timeout, ILogger logger)
        {
            return(await Task.Factory.StartNew(() =>
            {
                WfResult result = WfResult.Failed;
                //do thread hard abort if it is stuck on Run
                //using (token.Register(Thread.CurrentThread.Abort))
                //{
                for (int i = 0; i <= retry; i++)
                {
                    using (CancellationTokenSource timeoutCts = new CancellationTokenSource())
                        using (CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(token, timeoutCts.Token))
                        {
                            if (timeout > 0)
                            {
                                timeoutCts.CancelAfter(TimeSpan.FromSeconds(timeout));
                            }

                            try
                            {
                                token.ThrowIfCancellationRequested();
                                if (i > 0)
                                {
                                    logger.Information("Retry attempt {Count} on: {Message}", i, result.Message);

                                    if (delay > 0)
                                    {
                                        Task.Delay(TimeSpan.FromSeconds(delay), token).Wait();
                                    }
                                }

                                result = runner.Run(linkedCts.Token);
                            }
                            catch (ThreadAbortException ex)
                            {
                                logger.Error(ex, "ThreadAbortException: {0}", ex.Message);
                                result = WfResult.Create(WfStatus.Failed, ex.Message, -10);
                            }
                            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.Failed;
                                if (timeoutCts.IsCancellationRequested)
                                {
                                    result = WfResult.Create(WfStatus.Failed, "Step was cancelled on timeout", -10);
                                    logger.Error(aex, result.Message);
                                }

                                if (token.IsCancellationRequested)
                                {
                                    logger.Error(aex, "Step was cancelled");
                                    result = WfResult.Canceled;
                                }
                            }
                            catch (Exception ex)
                            {
                                logger.Error(ex, "Exception: {Message}", ex.Message);
                                result = WfResult.Create(WfStatus.Failed, ex.Message, -10);
                            }

                            if (result.StatusCode == WfStatus.Succeeded ||
                                token.IsCancellationRequested)
                            {
                                break;
                            }
                        }
                }

                return result;

                //}
            }));//, token);
        }