Remove multiple execution scopes (#427)

This commit is contained in:
Sipke Schoorstra 2020-10-26 15:32:02 +01:00 committed by GitHub
parent 16611e2a74
commit d5095f7a69
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 19 additions and 44 deletions

View file

@ -55,7 +55,6 @@ namespace Elsa.Activities.ControlFlow.Activities
if (index >= collection.Count)
{
context.EndScope();
CurrentIndex = 0;
return Done();
}
@ -63,11 +62,6 @@ namespace Elsa.Activities.ControlFlow.Activities
var value = collection[index];
CurrentIndex++;
if (index == 0)
{
context.BeginScope();
}
context.CurrentScope.SetVariable(IteratorName, value);
return Outcome(OutcomeNames.Iterate);

View file

@ -39,14 +39,10 @@ namespace Elsa.Activities.ControlFlow.Activities
{
var loop = await expressionEvaluator.EvaluateAsync(ConditionExpression, context, cancellationToken);
if (HasStarted)
context.EndScope();
if (loop)
{
HasStarted = true;
context.BeginScope();
return Outcome(OutcomeNames.Iterate);
}

View file

@ -16,7 +16,7 @@ namespace Elsa.Models
public Instant? FaultedAt { get; set; }
public Instant? AbortedAt { get; set; }
public IDictionary<string, ActivityInstance> Activities { get; set; } = new Dictionary<string, ActivityInstance>();
public Stack<WorkflowExecutionScope> Scopes { get; set; }
public WorkflowExecutionScope Scope { get; set; }
public Variables Input { get; set; }
public HashSet<BlockingActivity> BlockingActivities { get; set; }
public ICollection<LogEntry> ExecutionLog { get; set; }

View file

@ -28,11 +28,9 @@ namespace Elsa.Services.Models
Input = new Variables(input ?? Variables.Empty);
}
public Workflow()
{
Scopes = new Stack<WorkflowExecutionScope>(new[] { new WorkflowExecutionScope() });
Scope = new WorkflowExecutionScope();
BlockingActivities = new HashSet<IActivity>();
ExecutionLog = new List<LogEntry>();
}
@ -48,7 +46,7 @@ namespace Elsa.Services.Models
public Instant? AbortedAt { get; set; }
public ICollection<IActivity> Activities { get; } = new List<IActivity>();
public IList<Connection> Connections { get; } = new List<Connection>();
public Stack<WorkflowExecutionScope> Scopes { get; set; }
public WorkflowExecutionScope Scope { get; set; }
public HashSet<IActivity> BlockingActivities { get; set; }
public IList<LogEntry> ExecutionLog { get; set; }
public WorkflowFault Fault { get; set; }
@ -72,7 +70,7 @@ namespace Elsa.Services.Models
FaultedAt = FaultedAt,
AbortedAt = AbortedAt,
Activities = activities,
Scopes = new Stack<WorkflowExecutionScope>(Scopes),
Scope = Scope,
BlockingActivities = new HashSet<BlockingActivity>(
BlockingActivities.Select(x => new BlockingActivity(x.Id, x.Type)),
@ -100,12 +98,11 @@ namespace Elsa.Services.Models
FaultedAt = instance.FaultedAt;
AbortedAt = instance.AbortedAt;
ExecutionLog = instance.ExecutionLog.ToList();
Scope = instance.Scope;
BlockingActivities =
new HashSet<IActivity>(instance.BlockingActivities.Select(x => activityLookup[x.ActivityId]));
Scopes = new Stack<WorkflowExecutionScope>(instance.Scopes);
foreach (var activity in Activities)
{
activity.State = new JObject(instance.Activities[activity.Id].State);

View file

@ -35,7 +35,7 @@ namespace Elsa.Services.Models
public IEnumerable<IActivity> ScheduledActivities => scheduledActivities;
public bool IsFirstPass { get; set; }
public LogEntry CurrentLogEntry => Workflow.ExecutionLog.LastOrDefault();
public WorkflowExecutionScope CurrentScope => Workflow.Scopes.Peek();
public WorkflowExecutionScope CurrentScope => Workflow.Scope;
public Variables TransientState { get; } = new Variables();
public IActivity CurrentActivity { get; private set; }
public void ScheduleActivities(params IActivity[] activities) => ScheduleActivities((IEnumerable<IActivity>)activities);
@ -48,9 +48,6 @@ namespace Elsa.Services.Models
}
}
public void BeginScope() => Workflow.Scopes.Push(new WorkflowExecutionScope());
public void EndScope() => Workflow.Scopes.Pop();
public void ScheduleActivity(IActivity activity)
{
scheduledActivities.Push(activity);
@ -62,21 +59,9 @@ namespace Elsa.Services.Models
public IActivity PopScheduledHaltingActivity() => scheduledHaltingActivities.Pop();
public IWorkflowExpressionEvaluator ExpressionEvaluator { get; }
public void SetVariable(string name, object value)
{
// Get the first scope (starting from the oldest one) containing the variable (existing variable). Otherwise use the current scope (new variable declaration)
var scope = Workflow.Scopes.Reverse().FirstOrDefault(x => x.Variables.ContainsKey(name)) ?? CurrentScope;
scope.SetVariable(name, value);
}
public void SetVariable(string name, object value) => CurrentScope.SetVariable(name, value);
public T GetVariable<T>(string name) => (T) GetVariable(name);
public object GetVariable(string name)
{
// Get the first scope (starting from the newest one) containing the variable.
var scope = Workflow.Scopes.FirstOrDefault(x => x.Variables.ContainsKey(name)) ?? CurrentScope;
return scope.GetVariable(name);
}
public object GetVariable(string name) => CurrentScope.GetVariable(name);
public Task<T> EvaluateAsync<T>(IWorkflowExpression<T> expression, CancellationToken cancellationToken) =>
ExpressionEvaluator.EvaluateAsync(expression, this, cancellationToken);
@ -123,9 +108,6 @@ namespace Elsa.Services.Models
Workflow.Status = WorkflowStatus.Aborted;
}
public Variables GetVariables() => Workflow.Scopes
.Reverse()
.Select(x => x.Variables)
.Aggregate(Variables.Empty, (x, y) => new Variables(x.Union(y)));
public Variables GetVariables() => CurrentScope.Variables;
}
}

View file

@ -22,7 +22,7 @@ namespace Elsa.Persistence.MongoDb.Extensions
)
{
NodaTimeSerializers.Register();
RegisterEnumAsStringConvention();
RegisterConventions();
BsonSerializer.RegisterSerializer(new JObjectSerializer());
BsonSerializer.RegisterSerializer(new WorkflowExecutionScopeSerializer());
@ -90,11 +90,17 @@ namespace Elsa.Persistence.MongoDb.Extensions
return new MongoClient(connectionString);
}
private static void RegisterEnumAsStringConvention()
private static void RegisterConventions()
{
var pack = new ConventionPack { new EnumRepresentationConvention(BsonType.String) };
ConventionRegistry.Register("EnumStringConvention", pack, _ => true);
BsonClassMap.RegisterClassMap<WorkflowInstance>(cm =>
{
cm.AutoMap();
cm.SetIgnoreExtraElements(true);
});
}
}
}