private IRule <TModel> LoadLogic(string equationId) { StepTracer <LintTrace> trace = new StepTracer <LintTrace>(); StepTraceNode <LintTrace> root = trace.TraceFirst(new LintTrace(LintStatusOptions.Loading, "Loading Logic", equationId)); //Lint.... make sure we have everything we need first. Func <LogicDefine.Rule, StepTraceNode <LintTrace>, bool, IRule <TModel> > LoadRule = null; LoadRule = (rule, parentStep, inner) => { StepTraceNode <LintTrace> step = trace.TraceNext(parentStep, new LintTrace(LintStatusOptions.Inspecting, "Inspecting Rule", rule.Id)); IRule <TModel> toReturn = null; //if id is an equation, we are creating an expression //since we've formalized convention, we can just check that if (ConventionHelper.MatchesConvention(NamePrefixOptions.Equation, rule.Id, this.Configuration.Convention)) { LogicDefine.Equation eq = this.WorkflowManager.GetEquation(rule.Id); IRule <TModel> first = LoadRule(eq.First, step, true); IRule <TModel> second = LoadRule(eq.Second, step, true); toReturn = new Expression <TModel>(rule, eq.Condition, first, second, this, inner); } else { LogicDefine.Evaluator ev = this.WorkflowManager.GetEvaluator(rule.Id); toReturn = new Rule <TModel>(rule, this, inner); } return(toReturn); }; LogicDefine.Rule eqRule = equationId; IRule <TModel> loaded = LoadRule(eqRule, root, false); return(loaded); }
async Task <IEngineComplete <TModel> > IEngineFinalize <TModel> .FinalizeAsync(CancellationToken token) { StepTraceNode <ActivityProcess> mark = this.Tracer.CurrentStep = this.Tracer.TraceStep(this.Tracer.Root, new ActivityProcess("Finalize", ActivityStatusOptions.Engine_Finalizing, null)); if (this.ValidationContainer.ResolveValidations()) { foreach (KeyValuePair <string, IDeferredAction <TModel> > toFinalize in this.finalize) { this.Tracer.CurrentStep = this.Tracer.TraceStep(mark, new ActivityProcess(toFinalize.Key, ActivityStatusOptions.Action_Running, null)); await toFinalize.Value.CompleteAsync(this, new WorkflowEngineTrace(this.Tracer), token); } } foreach (KeyValuePair <string, IDeferredAction <TModel> > toFinalize in this.finalizeAlways) { this.Tracer.CurrentStep = this.Tracer.TraceStep(mark, new ActivityProcess(toFinalize.Key, ActivityStatusOptions.Action_Running, null)); await toFinalize.Value.CompleteAsync(this, new WorkflowEngineTrace(this.Tracer), token); } return(this); }
//this needs to // * ensure reaction rule is an equation // * ensure that any evaluators exist in the evaluators list private string LoadLogic(WorkDefine.Workflow workFlow, string equationId) { StepTraceNode <LintTrace> root = this.tracer.Root; //load conventions LogicDefine.Evaluator trueDef = workFlow.Evaluators.FirstOrDefault(z => z.Id == ConventionHelper.TrueEvaluator(this.config.Convention)); if (null == trueDef) { trueDef = new LogicDefine.Evaluator() { Id = ConventionHelper.TrueEvaluator(this.config.Convention), Description = "Always True" }; workFlow.Evaluators.Add(trueDef); } LogicDefine.Equation trueEqDef = workFlow.Equations.FirstOrDefault(z => z.Id == ConventionHelper.TrueEquation(this.config.Convention)); if (null == trueEqDef) { trueEqDef = new LogicDefine.Equation() { Condition = Logic.Operand.Or, First = trueDef.Id, Second = trueDef.Id, Id = ConventionHelper.TrueEquation(this.config.Convention) }; workFlow.Equations.Add(trueEqDef); } //Lint.... make sure we have everything we need first. Action <LogicDefine.Rule, StepTraceNode <LintTrace>, bool> LoadRule = null; LoadRule = (rule, parentStep, isRoot) => { StepTraceNode <LintTrace> step = this.tracer.TraceNext(parentStep, new LintTrace(LintStatusOptions.Inspecting, "Inspecting Rule", rule.Id)); //if id is an equation, we are creating an expression LogicDefine.Equation eq = workFlow.Equations.FirstOrDefault(g => g.Id.Equals(rule.Id)); if (null != eq) { if (null != eq.First) { LoadRule(eq.First, step, false); } else { eq.First = new LogicDefine.Rule() { Id = ConventionHelper.TrueEvaluator(this.config.Convention), Context = string.Empty, TrueCondition = true }; } if (null != eq.Second) { LoadRule(eq.Second.Id, step, false); } else { eq.Second = new LogicDefine.Rule() { Id = ConventionHelper.TrueEvaluator(this.config.Convention), Context = string.Empty, TrueCondition = true }; } if (!rule.TrueCondition) { //create a negation equation. string negationId = ConventionHelper.NegateEquationName(rule.Id, this.config.Convention); LogicDefine.Rule negated = (LogicDefine.Rule)rule.Clone(); //negated.TrueCondition = false; if (workFlow.Equations.Count(g => g.Id == negationId) == 0) { this.tracer.TraceNext(parentStep, new LintTrace(LintStatusOptions.InferringEquation, string.Format("Inferring negation equation from {0}", rule.Id), negationId)); LogicDefine.Equation toAdd = new LogicDefine.Equation() { First = negated, Id = negationId, Condition = Logic.Operand.And, Second = ConventionHelper.TrueEvaluator(this.config.Convention) }; workFlow.Equations.Add(toAdd); rule.TrueCondition = true; rule.Id = negationId; } } } else { //if reaction ruleid is not an equation, create an equation and update reaction LogicDefine.Evaluator ev = workFlow.Evaluators.FirstOrDefault(g => g.Id.Equals(rule.Id)); if (null == ev) { this.tracer.TraceNext(parentStep, new LintTrace(LintStatusOptions.LazyDefinition, "No definition found for evaluator", rule.Id)); ev = new LogicDefine.Evaluator() { Id = rule.Id, Description = string.Empty }; workFlow.Evaluators.Add(ev); } //if this is the rule referenced by the reaction, then create an equation also, //and update the equation. This isn't necessary, but consistent. if (isRoot) { LogicDefine.Rule cloned = (LogicDefine.Rule)rule.Clone(); string newId = string.Empty; Logic.Operand condition = Logic.Operand.And; if (rule.Id == ConventionHelper.TrueEquation(this.config.Convention)) { newId = ConventionHelper.TrueEquation(this.config.Convention); condition = Logic.Operand.Or; } else { newId = ConventionHelper.ChangePrefix(NamePrefixOptions.Evaluator, NamePrefixOptions.Equation, rule.Id, this.config.Convention); } if (!rule.TrueCondition) { newId = ConventionHelper.NegateEquationName(newId, this.config.Convention); } if (workFlow.Equations.Count(g => g.Id == newId) == 0) { this.tracer.TraceNext(parentStep, new LintTrace(LintStatusOptions.InferringEquation, string.Format("Inferring equation from {0}", rule.Id), newId)); workFlow.Equations.Add(new LogicDefine.Equation() { Condition = condition, First = cloned, Second = ConventionHelper.TrueEvaluator(this.config.Convention), Id = newId }); } rule.Id = newId; } } }; LogicDefine.Rule eqRule = equationId; LoadRule(eqRule, root, true); return(eqRule.Id); }
public async Task Execute(EngineStepTracer tracer, CancellationToken token) { this.engineRef.RunManager.CurrentActivity = this.activityDefinition; this.engineRef.CurrentActivityStatus = ActivityStatusOptions.Action_Running; //execute action //IAction<TModel> toExecute = this.engineRef.ImplementationManager.GetAction(this.activityDefinition.Action.Id); StepTraceNode <ActivityProcess> mark = this.engineRef.Tracer.CurrentStep = this.engineRef.Tracer.TraceStep( new ActivityProcess(this.activityDefinition.Id, ActivityStatusOptions.Activity_Running, null)); //try //{ // Stopwatch t = new Stopwatch(); t.Start(); // this.engineRef.Tracer.TraceStep( // new ActivityProcess(this.activityDefinition.Action.Id, ActivityStatusOptions.Action_Running, null)); // result = await toExecute.CompleteAsync(this.engineRef, new WorkflowEngineTrace(this.engineRef.Tracer), token); // t.Stop(); // this.engineRef.CurrentActivityStatus = ActivityStatusOptions.Action_Completed; // this.engineRef.Tracer.TraceStep(new ActivityProcess(this.activityDefinition.Action.Id, ActivityStatusOptions.Action_Completed, null, t.Elapsed)); //} //catch (System.Exception ex) //{ // this.engineRef.CurrentActivityStatus = ActivityStatusOptions.Action_Failed; // this.engineRef.Tracer.TraceStep(new ActivityProcess(this.activityDefinition.Action.Id, ActivityStatusOptions.Action_Failed, ex.Message)); //} //if i have reactions, loop through each and run if (this.Reactions.Count > 0) { StepTraceNode <ActivityProcess> reactionMark = this.engineRef.Tracer.CurrentStep = this.engineRef.Tracer.TraceStep( new ActivityProcess(this.activityDefinition.Id, ActivityStatusOptions.Action_Reacting, "React")); foreach (Reaction <TModel> react in this.Reactions) { if (react.Activity != null) { this.engineRef.Tracer.CurrentStep = this.engineRef.Tracer.TraceStep(reactionMark, new ActivityProcess(react.Activity.activityDefinition.Id, ActivityStatusOptions.Action_Reacting, "Evaluating")); bool doReact = await this.engineRef.Evaluate(react.LogicEquationId, token); if (doReact) { this.engineRef.Tracer.CurrentStep = this.engineRef.Tracer.TraceStep(reactionMark, new ActivityProcess(react.Activity.activityDefinition.Id, ActivityStatusOptions.Action_Reacting, "Reacting")); await react.Activity.Execute(this.engineRef.Tracer, token); } } else { this.engineRef.Tracer.CurrentStep = this.engineRef.Tracer.TraceStep(reactionMark, new ActivityProcess(react.Action.Id, ActivityStatusOptions.Action_Reacting, "Evaluating")); bool doReact = await this.engineRef.Evaluate(react.LogicEquationId, token); if (doReact) { IAction <TModel> reactionToExecute = this.engineRef.ImplementationManager.GetAction( new Define.ActionDefinition() { Id = react.Action.Id }); this.engineRef.Tracer.CurrentStep = this.engineRef.Tracer.TraceStep(reactionMark, new ActivityProcess(react.Action.Id, ActivityStatusOptions.Action_Running, "Reacting")); this.engineRef.RunManager.CurrentAction = react.Action; bool reactionResult = await reactionToExecute.CompleteAsync(this.engineRef, new WorkflowEngineTrace(this.engineRef.Tracer), token); } } } } this.Executed = true; }