Fix CompositeActivity behavior and update sample
This commit is contained in:
parent
0b40eb104d
commit
dd2004dd89
27
src/core/Elsa.Abstractions/Converters/StackJsonConverter.cs
Normal file
27
src/core/Elsa.Abstractions/Converters/StackJsonConverter.cs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Elsa.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Correctly deserializes a <see cref="Stack{T}"/> maintaining the order of the items.
|
||||
/// </summary>
|
||||
public class StackJsonConverter : JsonConverter
|
||||
{
|
||||
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
|
||||
{
|
||||
var newSerializer = new JsonSerializer();
|
||||
newSerializer.Serialize(writer, value);
|
||||
}
|
||||
|
||||
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
|
||||
{
|
||||
var newSerializer = new JsonSerializer();
|
||||
var list = newSerializer.Deserialize(reader, objectType)!;
|
||||
return Activator.CreateInstance(objectType, list);
|
||||
}
|
||||
|
||||
public override bool CanConvert(Type objectType) => objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(Stack<>);
|
||||
}
|
||||
}
|
||||
|
|
@ -21,12 +21,15 @@ namespace Elsa.Services
|
|||
{
|
||||
if (IsScheduled)
|
||||
{
|
||||
if (HasPendingChildren(context))
|
||||
return PostSchedule(Id);
|
||||
|
||||
context.WorkflowExecutionContext.WorkflowInstance.ParentActivities.Pop();
|
||||
IsScheduled = false;
|
||||
return Complete(context);
|
||||
}
|
||||
|
||||
var compositeActivityBlueprint = (ICompositeActivityBlueprint)context.ActivityBlueprint;
|
||||
|
||||
var compositeActivityBlueprint = (ICompositeActivityBlueprint) context.ActivityBlueprint;
|
||||
var startActivities = compositeActivityBlueprint.GetStartActivities().Select(x => x.Id).ToList();
|
||||
context.WorkflowExecutionContext.WorkflowInstance.ParentActivities.Push(Id);
|
||||
context.WorkflowExecutionContext.PostScheduleActivity(Id);
|
||||
|
|
@ -35,5 +38,14 @@ namespace Elsa.Services
|
|||
}
|
||||
|
||||
protected virtual IActivityExecutionResult Complete(ActivityExecutionContext context) => Done();
|
||||
|
||||
private static bool HasPendingChildren(ActivityExecutionContext context)
|
||||
{
|
||||
var children = ((CompositeActivityBlueprint) context.ActivityBlueprint).Activities.Select(x => x.Id).ToList();
|
||||
var workflowInstance = context.WorkflowExecutionContext.WorkflowInstance;
|
||||
var hasPendingPostScheduledChildren = workflowInstance.PostScheduledActivities.Any(x => children.Contains(x.ActivityId));
|
||||
var hasPendingScheduledChildren = workflowInstance.ScheduledActivities.Any(x => children.Contains(x.ActivityId));
|
||||
return hasPendingPostScheduledChildren || hasPendingScheduledChildren;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -97,8 +97,12 @@ namespace Elsa.Services.Models
|
|||
|
||||
public void SchedulePostActivities()
|
||||
{
|
||||
while (HasPostScheduledActivities)
|
||||
ScheduleActivity(WorkflowInstance.PostScheduledActivities.Pop());
|
||||
var activities = WorkflowInstance.PostScheduledActivities.Reverse();
|
||||
|
||||
foreach (var activity in activities)
|
||||
ScheduleActivity(activity);
|
||||
|
||||
WorkflowInstance.PostScheduledActivities.Clear();
|
||||
}
|
||||
|
||||
public object? GetOutputFrom(string activityName)
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ namespace Elsa.Serialization
|
|||
settings.Converters.Add(new StringEnumConverter(new DefaultNamingStrategy()));
|
||||
settings.Converters.Add(new TypeJsonConverter());
|
||||
settings.Converters.Add(new VersionOptionsJsonConverter());
|
||||
settings.Converters.Add(new StackJsonConverter());
|
||||
}
|
||||
|
||||
public static JsonSerializerSettings CreateDefaultJsonSerializationSettings()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
|
||||
using Elsa.Converters;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
using NodaTime;
|
||||
|
|
@ -19,7 +20,13 @@ namespace Elsa.Persistence.YesSql
|
|||
JsonSettings = new JsonSerializerSettings
|
||||
{
|
||||
TypeNameHandling = TypeNameHandling.Auto
|
||||
}.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
|
||||
};
|
||||
|
||||
JsonSettings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
|
||||
JsonSettings.Converters.Add(new StackJsonConverter());
|
||||
JsonSettings.Converters.Add(new VersionOptionsJsonConverter());
|
||||
JsonSettings.Converters.Add(new TypeJsonConverter());
|
||||
JsonSettings.Converters.Add(new StringEnumConverter(new DefaultNamingStrategy()));
|
||||
|
||||
JsonSettings.ContractResolver = new DefaultContractResolver
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
using Elsa.Activities.Console;
|
||||
using Elsa.Activities.ControlFlow;
|
||||
using Elsa.Activities.Timers;
|
||||
using Elsa.Builders;
|
||||
using Elsa.Samples.WhileLoopWorker.Services;
|
||||
using Elsa.Services;
|
||||
using NodaTime;
|
||||
|
||||
namespace Elsa.Samples.WhileLoopWorker.Activities
|
||||
{
|
||||
public class MakePhoneCall : CompositeActivity
|
||||
{
|
||||
private readonly PhoneCallService _phoneCallService;
|
||||
|
||||
public MakePhoneCall(PhoneCallService phoneCallService)
|
||||
{
|
||||
_phoneCallService = phoneCallService;
|
||||
}
|
||||
|
||||
public override void Build(ICompositeActivityBuilder composite)
|
||||
{
|
||||
composite
|
||||
.While(() => _phoneCallService.CallStatus != PhoneCallStatus.Finished,
|
||||
@while =>
|
||||
{
|
||||
@while
|
||||
.WriteLine("Ringgggg ringgg.")
|
||||
.Timer(Duration.FromSeconds(5))
|
||||
.Then(() => _phoneCallService.Progress())
|
||||
.WriteLine(() => $"Call status: {_phoneCallService.CallStatus}");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,10 +6,11 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0"/>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\core\Elsa\Elsa.csproj"/>
|
||||
<ProjectReference Include="..\..\..\core\Elsa\Elsa.csproj" />
|
||||
<ProjectReference Include="..\..\..\persistence\Elsa.Persistence.YesSql\Elsa.Persistence.YesSql.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ using Elsa.Samples.WhileLoopWorker.Workflows;
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Elsa.Persistence.InMemory;
|
||||
using Elsa.Persistence.YesSql.Extensions;
|
||||
using Elsa.Samples.WhileLoopWorker.Activities;
|
||||
|
||||
namespace Elsa.Samples.WhileLoopWorker
|
||||
{
|
||||
|
|
@ -16,11 +18,12 @@ namespace Elsa.Samples.WhileLoopWorker
|
|||
(_, services) =>
|
||||
{
|
||||
services
|
||||
.AddElsa()
|
||||
.AddElsa(options => options.UseYesSqlPersistence())
|
||||
.AddConsoleActivities()
|
||||
.AddTimerActivities()
|
||||
.AddSingleton<PhoneCallService>()
|
||||
.AddHostedService<PhoneCallWorker>()
|
||||
.AddActivity<MakePhoneCall>()
|
||||
.AddWorkflow<PhoneCallWorkflow>();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
using Elsa.Activities.Console;
|
||||
using Elsa.Activities.ControlFlow;
|
||||
using Elsa.Activities.Timers;
|
||||
using Elsa.Builders;
|
||||
using Elsa.Samples.WhileLoopWorker.Activities;
|
||||
using Elsa.Samples.WhileLoopWorker.Services;
|
||||
using NodaTime;
|
||||
|
||||
namespace Elsa.Samples.WhileLoopWorker.Workflows
|
||||
{
|
||||
|
|
@ -23,18 +21,8 @@ namespace Elsa.Samples.WhileLoopWorker.Workflows
|
|||
public void Build(IWorkflowBuilder workflow)
|
||||
{
|
||||
workflow
|
||||
.WriteLine("Simulating a phone call... ringgg ringgg.")
|
||||
.While(() => _phoneCallService.CallStatus != PhoneCallStatus.Finished,
|
||||
@while =>
|
||||
{
|
||||
@while
|
||||
.WriteLine("Ringgggg ringgg.")
|
||||
.WriteLine(() => $"Call status: {_phoneCallService.CallStatus}")
|
||||
.Timer(Duration.FromSeconds(5))
|
||||
.Then(() => _phoneCallService.Progress());
|
||||
|
||||
})
|
||||
.WriteLine(() => $"Call status: {_phoneCallService.CallStatus}")
|
||||
.WriteLine("Simulating a phone call...")
|
||||
.Then<MakePhoneCall>()
|
||||
.WriteLine("Workflow finished.");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue