From 4f092ee5e40c34f42b904befa22dbeefc406ce84 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Mon, 19 May 2025 22:01:20 +0200 Subject: [PATCH 1/6] Await HTTP resume callbacks --- .../Elsa.Http/Activities/HttpEndpoint.cs | 6 +-- .../Elsa.Http/Activities/HttpEndpointBase.cs | 4 +- ...pointActivityExecutionContextExtensions.cs | 41 ++++++++++--------- 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/modules/Elsa.Http/Activities/HttpEndpoint.cs b/src/modules/Elsa.Http/Activities/HttpEndpoint.cs index b38822b42..de63ed736 100644 --- a/src/modules/Elsa.Http/Activities/HttpEndpoint.cs +++ b/src/modules/Elsa.Http/Activities/HttpEndpoint.cs @@ -163,7 +163,7 @@ public class HttpEndpoint : Trigger { var path = Path.Get(context); var methods = SupportedMethods.GetOrDefault(context) ?? new List { HttpMethods.Get }; - context.WaitForHttpRequest(path, methods, OnResumeAsync); + await context.WaitForHttpRequest(path, methods, OnResumeAsync); } private async ValueTask OnResumeAsync(ActivityExecutionContext context) @@ -175,8 +175,8 @@ public class HttpEndpoint : Trigger { // We're executing in a non-HTTP context (e.g. in a virtual actor). // Create a bookmark to allow the invoker to export the state and resume execution from there. - context.CreateCrossBoundaryBookmark(); - return; + await context.CreateCrossBoundaryBookmark(); + return; } await HandleRequestAsync(context); diff --git a/src/modules/Elsa.Http/Activities/HttpEndpointBase.cs b/src/modules/Elsa.Http/Activities/HttpEndpointBase.cs index e3e3666fb..83794e28b 100644 --- a/src/modules/Elsa.Http/Activities/HttpEndpointBase.cs +++ b/src/modules/Elsa.Http/Activities/HttpEndpointBase.cs @@ -20,10 +20,10 @@ public abstract class HttpEndpointBase : Trigger { } - protected override void Execute(ActivityExecutionContext context) + protected override async ValueTask ExecuteAsync(ActivityExecutionContext context) { var options = GetOptions(); - context.WaitForHttpRequest(options, HttpRequestReceivedAsync); + await context.WaitForHttpRequest(options, HttpRequestReceivedAsync); } protected override IEnumerable GetTriggerPayloads(TriggerIndexingContext context) diff --git a/src/modules/Elsa.Http/Extensions/HttpEndpointActivityExecutionContextExtensions.cs b/src/modules/Elsa.Http/Extensions/HttpEndpointActivityExecutionContextExtensions.cs index 67bc08d52..bf790f2c4 100644 --- a/src/modules/Elsa.Http/Extensions/HttpEndpointActivityExecutionContextExtensions.cs +++ b/src/modules/Elsa.Http/Extensions/HttpEndpointActivityExecutionContextExtensions.cs @@ -3,33 +3,34 @@ using Elsa.Extensions; using Elsa.Http.Bookmarks; using Elsa.Workflows; using Elsa.Workflows.Models; +using System.Threading.Tasks; using Microsoft.AspNetCore.Routing.Patterns; namespace Elsa.Http.Extensions; public static class HttpEndpointActivityExecutionContextExtensions { - public static void WaitForHttpRequest(this ActivityExecutionContext context, string path, string method, ExecuteActivityDelegate? callback = null) +public static async ValueTask WaitForHttpRequest(this ActivityExecutionContext context, string path, string method, ExecuteActivityDelegate? callback = null) +{ + var options = new HttpEndpointOptions { - var options = new HttpEndpointOptions - { - Path = path, - Methods = [method] - }; - WaitForHttpRequest(context, options, callback); - } + Path = path, + Methods = [method] + }; + await WaitForHttpRequest(context, options, callback); +} - public static void WaitForHttpRequest(this ActivityExecutionContext context, string path, IEnumerable methods, ExecuteActivityDelegate? callback = null) +public static async ValueTask WaitForHttpRequest(this ActivityExecutionContext context, string path, IEnumerable methods, ExecuteActivityDelegate? callback = null) +{ + var options = new HttpEndpointOptions { - var options = new HttpEndpointOptions - { - Path = path, - Methods = methods.ToList() - }; - WaitForHttpRequest(context, options, callback); - } + Path = path, + Methods = methods.ToList() + }; + await WaitForHttpRequest(context, options, callback); +} - public static void WaitForHttpRequest(this ActivityExecutionContext context, HttpEndpointOptions options, ExecuteActivityDelegate? callback = null) + public static async ValueTask WaitForHttpRequest(this ActivityExecutionContext context, HttpEndpointOptions options, ExecuteActivityDelegate? callback = null) { var path = options.Path; if (path.Contains("//")) @@ -42,7 +43,8 @@ public static class HttpEndpointActivityExecutionContextExtensions return; } - callback?.Invoke(context); + if (callback is not null) + await callback(context); } public static IEnumerable GetHttpEndpointStimuli(this TriggerIndexingContext context, string path, string method) @@ -81,7 +83,7 @@ public static class HttpEndpointActivityExecutionContextExtensions .ToArray(); } - internal static void CreateCrossBoundaryBookmark(this ActivityExecutionContext context, ExecuteActivityDelegate? callback = null) + internal static ValueTask CreateCrossBoundaryBookmark(this ActivityExecutionContext context, ExecuteActivityDelegate? callback = null) { var bookmarkOptions = new CreateBookmarkArgs { @@ -90,5 +92,6 @@ public static class HttpEndpointActivityExecutionContextExtensions Metadata = BookmarkMetadata.HttpCrossBoundary, }; context.CreateBookmark(bookmarkOptions); + return ValueTask.CompletedTask; } } \ No newline at end of file From 301dea4c4485107ab3ce80f1286c8feac986abc0 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Mon, 19 May 2025 22:02:49 +0200 Subject: [PATCH 2/6] Update HttpEndpoint.cs --- src/modules/Elsa.Http/Activities/HttpEndpoint.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/modules/Elsa.Http/Activities/HttpEndpoint.cs b/src/modules/Elsa.Http/Activities/HttpEndpoint.cs index de63ed736..b61d3632c 100644 --- a/src/modules/Elsa.Http/Activities/HttpEndpoint.cs +++ b/src/modules/Elsa.Http/Activities/HttpEndpoint.cs @@ -163,7 +163,7 @@ public class HttpEndpoint : Trigger { var path = Path.Get(context); var methods = SupportedMethods.GetOrDefault(context) ?? new List { HttpMethods.Get }; - await context.WaitForHttpRequest(path, methods, OnResumeAsync); + await context.WaitForHttpRequest(path, methods, OnResumeAsync); } private async ValueTask OnResumeAsync(ActivityExecutionContext context) @@ -175,8 +175,8 @@ public class HttpEndpoint : Trigger { // We're executing in a non-HTTP context (e.g. in a virtual actor). // Create a bookmark to allow the invoker to export the state and resume execution from there. - await context.CreateCrossBoundaryBookmark(); - return; + context.CreateCrossBoundaryBookmark(); + return; } await HandleRequestAsync(context); @@ -497,4 +497,4 @@ public class HttpEndpoint : Trigger return routeData; } -} \ No newline at end of file +} From 6ee74f4c7351d62b4299137d53b222f11af50f0a Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Mon, 19 May 2025 22:03:20 +0200 Subject: [PATCH 3/6] Update HttpEndpointActivityExecutionContextExtensions.cs --- .../HttpEndpointActivityExecutionContextExtensions.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/modules/Elsa.Http/Extensions/HttpEndpointActivityExecutionContextExtensions.cs b/src/modules/Elsa.Http/Extensions/HttpEndpointActivityExecutionContextExtensions.cs index bf790f2c4..3fee6b627 100644 --- a/src/modules/Elsa.Http/Extensions/HttpEndpointActivityExecutionContextExtensions.cs +++ b/src/modules/Elsa.Http/Extensions/HttpEndpointActivityExecutionContextExtensions.cs @@ -83,7 +83,7 @@ public static async ValueTask WaitForHttpRequest(this ActivityExecutionContext c .ToArray(); } - internal static ValueTask CreateCrossBoundaryBookmark(this ActivityExecutionContext context, ExecuteActivityDelegate? callback = null) + internal static void CreateCrossBoundaryBookmark(this ActivityExecutionContext context, ExecuteActivityDelegate? callback = null) { var bookmarkOptions = new CreateBookmarkArgs { @@ -92,6 +92,5 @@ public static async ValueTask WaitForHttpRequest(this ActivityExecutionContext c Metadata = BookmarkMetadata.HttpCrossBoundary, }; context.CreateBookmark(bookmarkOptions); - return ValueTask.CompletedTask; } -} \ No newline at end of file +} From 23622b567978d70419b1fd1ee58a96ff67fb0ac9 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Mon, 19 May 2025 22:07:30 +0200 Subject: [PATCH 4/6] Refactor to use `WaitForHttpRequestAsync` consistently. Replaced `WaitForHttpRequest` with `WaitForHttpRequestAsync` across the codebase to align with asynchronous naming conventions. This change improves clarity and maintains consistency in method naming. --- src/modules/Elsa.Http/Activities/HttpEndpoint.cs | 2 +- src/modules/Elsa.Http/Activities/HttpEndpointBase.cs | 2 +- .../HttpEndpointActivityExecutionContextExtensions.cs | 11 +++++------ 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/modules/Elsa.Http/Activities/HttpEndpoint.cs b/src/modules/Elsa.Http/Activities/HttpEndpoint.cs index b61d3632c..6db32f823 100644 --- a/src/modules/Elsa.Http/Activities/HttpEndpoint.cs +++ b/src/modules/Elsa.Http/Activities/HttpEndpoint.cs @@ -163,7 +163,7 @@ public class HttpEndpoint : Trigger { var path = Path.Get(context); var methods = SupportedMethods.GetOrDefault(context) ?? new List { HttpMethods.Get }; - await context.WaitForHttpRequest(path, methods, OnResumeAsync); + await context.WaitForHttpRequestAsync(path, methods, OnResumeAsync); } private async ValueTask OnResumeAsync(ActivityExecutionContext context) diff --git a/src/modules/Elsa.Http/Activities/HttpEndpointBase.cs b/src/modules/Elsa.Http/Activities/HttpEndpointBase.cs index 83794e28b..9257a73c1 100644 --- a/src/modules/Elsa.Http/Activities/HttpEndpointBase.cs +++ b/src/modules/Elsa.Http/Activities/HttpEndpointBase.cs @@ -23,7 +23,7 @@ public abstract class HttpEndpointBase : Trigger protected override async ValueTask ExecuteAsync(ActivityExecutionContext context) { var options = GetOptions(); - await context.WaitForHttpRequest(options, HttpRequestReceivedAsync); + await context.WaitForHttpRequestAsync(options, HttpRequestReceivedAsync); } protected override IEnumerable GetTriggerPayloads(TriggerIndexingContext context) diff --git a/src/modules/Elsa.Http/Extensions/HttpEndpointActivityExecutionContextExtensions.cs b/src/modules/Elsa.Http/Extensions/HttpEndpointActivityExecutionContextExtensions.cs index 3fee6b627..ca62a0782 100644 --- a/src/modules/Elsa.Http/Extensions/HttpEndpointActivityExecutionContextExtensions.cs +++ b/src/modules/Elsa.Http/Extensions/HttpEndpointActivityExecutionContextExtensions.cs @@ -3,34 +3,33 @@ using Elsa.Extensions; using Elsa.Http.Bookmarks; using Elsa.Workflows; using Elsa.Workflows.Models; -using System.Threading.Tasks; using Microsoft.AspNetCore.Routing.Patterns; namespace Elsa.Http.Extensions; public static class HttpEndpointActivityExecutionContextExtensions { -public static async ValueTask WaitForHttpRequest(this ActivityExecutionContext context, string path, string method, ExecuteActivityDelegate? callback = null) +public static async ValueTask WaitForHttpRequestAsync(this ActivityExecutionContext context, string path, string method, ExecuteActivityDelegate? callback = null) { var options = new HttpEndpointOptions { Path = path, Methods = [method] }; - await WaitForHttpRequest(context, options, callback); + await WaitForHttpRequestAsync(context, options, callback); } -public static async ValueTask WaitForHttpRequest(this ActivityExecutionContext context, string path, IEnumerable methods, ExecuteActivityDelegate? callback = null) +public static async ValueTask WaitForHttpRequestAsync(this ActivityExecutionContext context, string path, IEnumerable methods, ExecuteActivityDelegate? callback = null) { var options = new HttpEndpointOptions { Path = path, Methods = methods.ToList() }; - await WaitForHttpRequest(context, options, callback); + await WaitForHttpRequestAsync(context, options, callback); } - public static async ValueTask WaitForHttpRequest(this ActivityExecutionContext context, HttpEndpointOptions options, ExecuteActivityDelegate? callback = null) + public static async ValueTask WaitForHttpRequestAsync(this ActivityExecutionContext context, HttpEndpointOptions options, ExecuteActivityDelegate? callback = null) { var path = options.Path; if (path.Contains("//")) From 81943317f31bed05749b43680360129b283bb8e5 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Mon, 19 May 2025 22:11:08 +0200 Subject: [PATCH 5/6] Add 'codex/*' branch to workflow path filters This update ensures that actions in the workflow are triggered for changes in branches following the 'codex/*' naming convention. It aligns the path filters with the branching strategy and improves CI/CD coverage. --- .github/workflows/packages.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/packages.yml b/.github/workflows/packages.yml index e3f8ea3da..ec55bf739 100644 --- a/.github/workflows/packages.yml +++ b/.github/workflows/packages.yml @@ -11,6 +11,7 @@ on: - 'enh/*' - 'rc/*' - 'develop/*' + - 'codex/*' release: types: [ prereleased, published ] env: From 807722f91eaac0543ddaed20e25c8af124a03de2 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 20 May 2025 10:45:55 +0200 Subject: [PATCH 6/6] Remove ReadLine activity from automatic registration The ReadLine activity was removed as it can cause hanging containers when awaiting user input. This change requires explicit opt-in for its usage, improving default workflow behavior and avoiding unintended issues. --- src/modules/Elsa/Features/ElsaFeature.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/modules/Elsa/Features/ElsaFeature.cs b/src/modules/Elsa/Features/ElsaFeature.cs index f6941f456..eb4a4b508 100644 --- a/src/modules/Elsa/Features/ElsaFeature.cs +++ b/src/modules/Elsa/Features/ElsaFeature.cs @@ -40,7 +40,10 @@ public class ElsaFeature : FeatureBase .UseWorkflowManagement(management => { if (!DisableAutomaticActivityRegistration) - management.AddActivitiesFrom(); + management + .AddActivitiesFrom() + .RemoveActivity() // ReadLine is not commonly used and can cause "hanging" containers when awaiting user input. Better to opt-in explicitly. + ; }); } } \ No newline at end of file