Skip to content

Commit 761bc43

Browse files
authored
Merge pull request #406 from serverlessworkflow/fix-ignore-skipped-task-directive
Fixed the WorkflowExecutor and DoTaskExecutor to ignore the flow directive of skipped tasks
2 parents 2b7a777 + 185bcaa commit 761bc43

File tree

4 files changed

+12
-11
lines changed

4 files changed

+12
-11
lines changed

src/runner/Synapse.Runner/Extensions/WorkflowDefinitionExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public static class WorkflowDefinitionExtensions
2828
public static MapEntry<string, TaskDefinition>? GetTaskAfter(this WorkflowDefinition workflow, TaskInstance after)
2929
{
3030
ArgumentNullException.ThrowIfNull(after);
31-
switch (after.Next)
31+
switch (after.Status == TaskInstanceStatus.Skipped ? FlowDirective.Continue : after.Next)
3232
{
3333
case FlowDirective.Continue:
3434
var afterTask = workflow.Do[after.Name!];

src/runner/Synapse.Runner/Services/Executors/DoTaskExecutor.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,20 +98,19 @@ protected virtual async Task OnSubTaskFaultAsync(ITaskExecutor executor, Cancell
9898
/// <returns>A new awaitable <see cref="Task"/></returns>
9999
protected virtual async Task OnSubtaskCompletedAsync(ITaskExecutor executor, CancellationToken cancellationToken)
100100
{
101-
ArgumentNullException.ThrowIfNull(executor);
102101
var last = executor.Task.Instance;
103102
var output = executor.Task.Output!;
104103
var nextDefinition = this.Task.Definition.Do.GetTaskAfter(last);
105104
this.Executors.Remove(executor);
106105
if (this.Task.ContextData != executor.Task.ContextData) await this.Task.SetContextDataAsync(executor.Task.ContextData, cancellationToken).ConfigureAwait(false);
107106
if (nextDefinition == null || nextDefinition.Value == null)
108107
{
109-
await this.SetResultAsync(output, last.Next == FlowDirective.End ? FlowDirective.End : this.Task.Definition.Then, cancellationToken).ConfigureAwait(false);
108+
await this.SetResultAsync(output, last.Status != TaskInstanceStatus.Skipped && last.Next == FlowDirective.End ? FlowDirective.End : this.Task.Definition.Then, cancellationToken).ConfigureAwait(false);
110109
return;
111110
}
112111
var nextDefinitionIndex = this.Task.Definition.Do.Keys.ToList().IndexOf(nextDefinition.Key);
113112
TaskInstance next;
114-
switch (executor.Task.Instance.Next)
113+
switch (executor.Task.Instance.Status == TaskInstanceStatus.Skipped ? FlowDirective.Continue : executor.Task.Instance.Next)
115114
{
116115
case FlowDirective.End:
117116
await this.SetResultAsync(output, FlowDirective.End, cancellationToken).ConfigureAwait(false);

src/runner/Synapse.Runner/Services/Executors/OpenApiCallExecutor.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,16 @@ protected override async Task DoInitializeAsync(CancellationToken cancellationTo
109109
this.OpenApi = (OpenApiCallDefinition)this.JsonSerializer.Convert(this.Task.Definition.With, typeof(OpenApiCallDefinition))!;
110110
using var httpClient = this.HttpClientFactory.CreateClient();
111111
await httpClient.ConfigureAuthenticationAsync(this.Task.Workflow.Definition, this.OpenApi.Document.Endpoint.Authentication, this.ServiceProvider, cancellationToken).ConfigureAwait(false);
112-
var uri = StringFormatter.NamedFormat(this.OpenApi.Document.EndpointUri.OriginalString, this.Task.Input.ToDictionary());
113-
if (uri.IsRuntimeExpression()) uri = await this.Task.Workflow.Expressions.EvaluateAsync<string>(uri, this.Task.Input, this.GetExpressionEvaluationArguments(), cancellationToken).ConfigureAwait(false);
114-
using var request = new HttpRequestMessage(HttpMethod.Get, uri);
112+
var uriString = StringFormatter.NamedFormat(this.OpenApi.Document.EndpointUri.OriginalString, this.Task.Input.ToDictionary());
113+
if (uriString.IsRuntimeExpression()) uriString = await this.Task.Workflow.Expressions.EvaluateAsync<string>(uriString, this.Task.Input, this.GetExpressionEvaluationArguments(), cancellationToken).ConfigureAwait(false);
114+
if (string.IsNullOrWhiteSpace(uriString)) throw new NullReferenceException("The OpenAPI endpoint URI cannot be null or whitespace");
115+
if (!Uri.TryCreate(uriString, UriKind.RelativeOrAbsolute, out var uri) || uri == null) throw new Exception($"Failed to parse the specified string '{uriString}' into a new URI");
116+
using var request = new HttpRequestMessage(HttpMethod.Get, uriString);
115117
using var response = await httpClient.SendAsync(request, cancellationToken).ConfigureAwait(false);
116118
if (!response.IsSuccessStatusCode)
117119
{
118120
var responseContent = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
119-
this.Logger.LogInformation("Failed to retrieve the OpenAPI document at location '{uri}'. The remote server responded with a non-success status code '{statusCode}'.", this.OpenApi.Document.EndpointUri, response.StatusCode);
121+
this.Logger.LogInformation("Failed to retrieve the OpenAPI document at location '{uri}'. The remote server responded with a non-success status code '{statusCode}'.", uri, response.StatusCode);
120122
this.Logger.LogDebug("Response content:\r\n{responseContent}", responseContent ?? "None");
121123
response.EnsureSuccessStatusCode();
122124
}
@@ -125,11 +127,11 @@ protected override async Task DoInitializeAsync(CancellationToken cancellationTo
125127
var operation = this.Document.Paths
126128
.SelectMany(p => p.Value.Operations)
127129
.FirstOrDefault(o => o.Value.OperationId == this.OpenApi.OperationId);
128-
if (operation.Value == null) throw new NullReferenceException($"Failed to find an operation with id '{this.OpenApi.OperationId}' in OpenAPI document at '{this.OpenApi.Document.EndpointUri}'");
130+
if (operation.Value == null) throw new NullReferenceException($"Failed to find an operation with id '{this.OpenApi.OperationId}' in OpenAPI document at '{uri}'");
129131
this.HttpMethod = operation.Key.ToHttpMethod();
130132
this.Operation = operation.Value;
131133
this.Servers = this.Document.Servers.Select(s => s.Url).ToList();
132-
if (this.Servers.Count == 0) this.Servers.Add(this.OpenApi.Document.EndpointUri.OriginalString.Replace(this.OpenApi.Document.EndpointUri.PathAndQuery, string.Empty));
134+
if (this.Servers.Count == 0) this.Servers.Add(uri.OriginalString.Replace(uri.PathAndQuery, string.Empty));
133135
var path = this.Document.Paths.Single(p => p.Value.Operations.Any(o => o.Value.OperationId == operation.Value.OperationId));
134136
this.Path = path.Key;
135137
await this.BuildParametersAsync(cancellationToken).ConfigureAwait(false);

src/runner/Synapse.Runner/Services/WorkflowExecutor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ protected virtual async Task OnTaskFaultedAsync(ITaskExecutor executor, Cancella
265265
/// <returns>A new awaitable <see cref="Task"/></returns>
266266
protected virtual async Task OnTaskCompletedAsync(ITaskExecutor executor, CancellationToken cancellationToken)
267267
{
268-
var nextDefinition = executor.Task.Instance.Next switch
268+
var nextDefinition = (executor.Task.Instance.Status == TaskInstanceStatus.Skipped ? FlowDirective.Continue : executor.Task.Instance.Next) switch
269269
{
270270
FlowDirective.End or FlowDirective.Exit => null,
271271
_ => this.Workflow.Definition.GetTaskAfter(executor.Task.Instance)

0 commit comments

Comments
 (0)