/// <summary>
        /// Finilizes the Workflow completion with backend.
        /// Perform Workflow History Cleanup based on retention policy.
        /// </summary>
        /// <param name="wf"></param>
        /// <param name="Result"></param>
        /// <returns></returns>
        public bool WorkflowFinalize(Workflow wf, WfResult Result)
        {
            if (wf == null || wf.RunId == 0)
            {
                throw new InvalidDataException("Workflow object can not be finalized");
            }


            short  status_id = DBStatus.WfValue(Result.StatusCode);
            string cmd_text  = String.Format(WORKFLOW_FINALIZE_QUERY,
                                             wf.WorkflowId,
                                             wf.RunId,
                                             status_id,
                                             wf.HistoryRetention,
                                             ((_debug) ? 1 : 0));

            ExecuteNonQuery(cmd_text);

            return(true);
        }
        /// <summary>
        /// Reports execution results to the backend
        /// </summary>
        /// <param name="wfs"></param>
        /// <param name="Result"></param>
        /// <returns></returns>
        public bool WorkflowStepStatusSet(WorkflowStep wfs, WfResult Result)
        {
            if (wfs == null || wfs.RunId == 0)
            {
                throw new InvalidDataException("WorkflowStep object is not in the correct state");
            }


            short  status_id = DBStatus.WfValue(Result.StatusCode);
            string cmd_text  = String.Format(WORKFLOW_STEP_STATUS_SET_QUERY,
                                             wfs.WorkflowId,
                                             wfs.StepId,
                                             wfs.RunId,
                                             status_id,
                                             Result.ErrorCode);

            ExecuteNonQuery(cmd_text);

            return(true);
        }
        /// <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);
        }
        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);
        }
示例#5
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);
        }
示例#6
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);
        }
示例#7
0
 public void SetTo(WfResult result)
 {
     this.StatusCode = result.StatusCode;
     this.Message    = result.Message;
     this.ErrorCode  = result.ErrorCode;
 }
示例#8
0
 public static WfResult Create(WfResult result)
 {
     return(new WfResult(result.StatusCode, result.Message, result.ErrorCode));
 }