/// <summary> /// Try to get next step to continue execution /// </summary> /// <param name="step"></param> /// <param name="env"></param> /// <param name="nextStep"></param> /// <returns></returns> private bool TryGetNextStep(StepRuntime step, IProcessRuntimeEnvironment env, out StepRuntime nextStep) { nextStep = null; // check for specific transition name var linkRuntimes = _links.Where(l => l.SourceStepId == step.Id).ToList(); if (linkRuntimes.Count == 1) { nextStep = _steps.FirstOrDefault(s => s.Id == linkRuntimes[0].TargetStepId); return(true); } if (!string.IsNullOrEmpty(env.Transition)) { LinkRuntime linkRuntime = linkRuntimes.FirstOrDefault(l => l.Definition.Name == env.Transition); nextStep = linkRuntime == null ? null : _steps.FirstOrDefault(s => s.Id == linkRuntime.TargetStepId); return(nextStep != null); } foreach (LinkRuntime link in linkRuntimes) { if (link.Evaluate(env).Result) { nextStep = _steps.FirstOrDefault(s => s.Id == link.TargetStepId); break; } } return(nextStep != null); }
/// <summary> /// Step Execution Read moves the workflow to its next step. /// </summary> /// <param name="rt"></param> /// <param name="env"></param> /// <returns></returns> protected virtual Tuple <ExecutionResult, StepRuntime> OnStepExecutionReady(StepRuntime rt, IProcessRuntimeEnvironment env) { _lastExecutedStep = rt; var onExitResult = rt.ValidateOnExit(env).Result; if (onExitResult.Valid) { StepRuntime next; if (TryGetNextStep(rt, env, out next)) { SuspendedInStep = null; State = ProcessStateEnum.Ready; return(new Tuple <ExecutionResult, StepRuntime>( new ExecutionResult(StepExecutionStatusEnum.Ready), next)); } if (rt.IsEnd) { SuspendedInStep = null; State = ProcessStateEnum.Completed; return(new Tuple <ExecutionResult, StepRuntime>(new ExecutionResult(StepExecutionStatusEnum.Completed), rt)); } else { return(new Tuple <ExecutionResult, StepRuntime>(new ExecutionResult(StepExecutionStatusEnum.Ready), next)); } } OnExitValidationError(onExitResult.Messages); State = ProcessStateEnum.Failed; return(new Tuple <ExecutionResult, StepRuntime>( new ExecutionResult(StepExecutionStatusEnum.Failed, null, onExitResult.Messages), rt)); }
/// <summary> /// /// </summary> /// <param name="rt"></param> /// <param name="env"></param> /// <param name="messages"></param> /// <returns></returns> protected virtual bool TryEnter(StepRuntime rt, IProcessRuntimeEnvironment env, out string[] messages) { messages = EmptyStrArr; AsyncValidationResult onEnterResult = rt.ValidateOnEnter(env).Result; if (!onEnterResult.Valid) { messages = onEnterResult.Messages; } return(onEnterResult.Valid); }
/// <summary> /// Execute Single Step in the workflow /// </summary> /// <returns> /// This method returns a tuple of two elements: /// <see cref="ExecutionResult"/> /// <see cref="StepRuntime"/> /// Next Step in Execution flow /// If the execution result has value of Suspend /// </returns> public virtual Tuple <ExecutionResult, StepRuntime> Execute(StepRuntime rt, IProcessRuntimeEnvironment env) { Func <StateActionParams, Tuple <ExecutionResult, StepRuntime> > f; if (!StatusActions.TryGetValue(State, out f)) { throw new InvalidProcessStateException($"Process Id={Id} State={State} is not supported."); } return(f(new StateActionParams { Process = this, Step = rt, Env = env })); }
/// <summary> /// Constructor /// </summary> /// <param name="id"></param> /// <param name="links"></param> /// <param name="steps"></param> /// <param name="variables"></param> /// <param name="suspendedInStep"></param> /// <param name="status"></param> public ProcessRuntime(Guid id, IEnumerable <LinkRuntime> links, IEnumerable <StepRuntime> steps, IEnumerable <VariableRuntime> variables, IEnumerable <TagRuntime> tags, StepRuntime suspendedInStep, ProcessStateEnum status ) { _links = links.ToList(); _steps = steps.ToList(); _variables = variables.ToList(); _tags = tags.ToList(); State = status; Id = id; SuspendedInStep = suspendedInStep; }
/// <summary> /// Instantiate a process with associated step and state /// </summary> /// <param name="id"></param> /// <param name="pd"></param> /// <param name="step"></param> /// <param name="status"></param> /// <returns></returns> protected virtual ProcessRuntime Create(Guid id, ProcessDefinition pd, string step, ProcessStateEnum status) { IEnumerable <LinkRuntime> linkRuntimes = pd.Links.Select(ld => new LinkRuntime(ld)).ToList(); IEnumerable <StepRuntime> stepRuntimes = pd.Steps.Select(sd => new StepRuntime(sd, linkRuntimes.Where(l => l.SourceStepId == sd.Id).ToArray())); IEnumerable <VariableRuntime> varRuntimes = pd.Variables.Select(vd => new VariableRuntime(vd)).ToList(); StepDefinition stepDef = pd.Steps.SingleOrDefault(s => s.StepId == step); StepRuntime suspended = stepDef == null ? null : new StepRuntime(stepDef, linkRuntimes.Where(l => l.SourceStepId == stepDef.Id).ToArray()); IEnumerable <TagRuntime> tagRuntimes = pd.Tags.Select(t => new TagRuntime(t)).ToList(); return(new ProcessRuntime( id, linkRuntimes, stepRuntimes, varRuntimes, tagRuntimes, suspended, status)); }
/// <summary> /// On Execute step /// </summary> /// <param name="rt"></param> /// <param name="env"></param> /// <returns></returns> protected virtual Tuple <ExecutionResult, StepRuntime> OnExecute(StepRuntime rt, IProcessRuntimeEnvironment env) { BeforeExecute(); string[] errors; if (!TryEnter(rt, env, out errors)) { State = ProcessStateEnum.Failed; OnEntryValidationError(errors); return(new Tuple <ExecutionResult, StepRuntime>(new ExecutionResult(StepExecutionStatusEnum.Failed), null)); } State = ProcessStateEnum.Ready; _lastExecutedStep = rt; var stepExecutionResult = rt.ExecuteAsync(env).Result; Func <StateActionParams, Tuple <ExecutionResult, StepRuntime> > f; if (!PostStatusActions.TryGetValue(stepExecutionResult.Status, out f)) { throw new InvalidProcessStateException( $"Step Execution status {stepExecutionResult.Status} is not supported for Process Id={Id}"); } try { return(f(new StateActionParams { Step = rt, Process = this, Env = env, Result = stepExecutionResult })); } finally { AfterExecute(); } }
/// <summary> /// Unfreeze the process /// </summary> /// <param name="processRuntimeId"></param> /// <param name="runtime"></param> /// <param name="nextStep"></param> /// <param name="collection"></param> /// <returns></returns> public virtual bool TryUnfreeze(Guid processRuntimeId, out IProcessRuntime runtime, out StepRuntime nextStep, out IPropertySetCollection collection) { throw new NotImplementedException(); }
protected virtual void OnStepExecutionFailed(StepRuntime failedStep, string[] messages) { _lastExecutedStep = failedStep; _errors.AddRange(messages); }
/// <summary> /// The flow is suspended; /// It can be persisted and destroyed or keep in memory and "rectified" /// </summary> protected virtual void OnSuspend(StepRuntime suspendedStep) { _lastExecutedStep = suspendedStep; State = ProcessStateEnum.Suspended; SuspendedInStep = suspendedStep; }
public ScriptHandler(StepRuntime step) { _script = new CsScriptRuntime(step._stepDef.StepHandler.Script); }
public AsmLoadHandler(StepRuntime step) { _step = step; }
public TaskServiceHandler(StepRuntime step) { _step = step; }
public IoCServiceHandler(StepRuntime step) { _step = step; }