Skip to content

Commit df3b47a

Browse files
authored
Command reordering in Core (#315)
Fixes #312
1 parent 32d1931 commit df3b47a

24 files changed

+1829
-127
lines changed

src/Temporalio/Bridge/Cargo.lock

Lines changed: 16 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Temporalio/Worker/TemporalWorker.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,7 @@ public TemporalWorker(IWorkerClient client, TemporalWorkerOptions options)
8989
OnTaskStarting: options.OnTaskStarting,
9090
OnTaskCompleted: options.OnTaskCompleted,
9191
RuntimeMetricMeter: MetricMeter,
92-
WorkerLevelFailureExceptionTypes: options.WorkflowFailureExceptionTypes,
93-
DisableCompletionCommandReordering: options.DisableWorkflowCompletionCommandReordering));
92+
WorkerLevelFailureExceptionTypes: options.WorkflowFailureExceptionTypes));
9493
}
9594
}
9695

src/Temporalio/Worker/TemporalWorkerOptions.cs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -297,15 +297,6 @@ public TemporalWorkerOptions()
297297
internal Func<WorkflowInstanceDetails, IWorkflowInstance> WorkflowInstanceFactory { get; set; } =
298298
DefaultWorkflowInstanceFactory;
299299

300-
/// <summary>
301-
/// Gets or sets a value indicating whether the workflow completion command reordering will
302-
/// apply.
303-
/// </summary>
304-
/// <remarks>
305-
/// This is visible for testing only.
306-
/// </remarks>
307-
internal bool DisableWorkflowCompletionCommandReordering { get; set; }
308-
309300
/// <summary>
310301
/// Add the given delegate with <see cref="ActivityAttribute" /> as an activity. This is
311302
/// usually a method reference.

src/Temporalio/Worker/WorkflowInstance.cs

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ internal class WorkflowInstance : TaskScheduler, IWorkflowInstance, IWorkflowCon
6868
private readonly Action<WorkflowInstance> onTaskStarting;
6969
private readonly Action<WorkflowInstance, Exception?> onTaskCompleted;
7070
private readonly IReadOnlyCollection<Type>? workerLevelFailureExceptionTypes;
71-
private readonly bool disableCompletionCommandReordering;
7271
private readonly Handlers inProgressHandlers = new();
7372
private WorkflowActivationCompletion? completion;
7473
// Will be set to null after last use (i.e. when workflow actually started)
@@ -190,7 +189,6 @@ public WorkflowInstance(WorkflowInstanceDetails details)
190189
Random = new(details.Start.RandomnessSeed);
191190
TracingEventsEnabled = !details.DisableTracingEvents;
192191
workerLevelFailureExceptionTypes = details.WorkerLevelFailureExceptionTypes;
193-
disableCompletionCommandReordering = details.DisableCompletionCommandReordering;
194192
}
195193

196194
/// <summary>
@@ -580,8 +578,8 @@ public WorkflowActivationCompletion Activate(WorkflowActivation act)
580578
}
581579
}
582580

583-
// Maybe apply workflow completion command reordering logic
584-
ApplyCompletionCommandReordering(act, completion, out var workflowComplete);
581+
// Maybe apply legacy workflow completion command reordering logic
582+
ApplyLegacyCompletionCommandReordering(act, completion, out var workflowComplete);
585583

586584
// Log warnings if we have completed
587585
if (workflowComplete && !IsReplaying)
@@ -1425,22 +1423,13 @@ private string GetStackTrace()
14251423
}).Where(s => !string.IsNullOrEmpty(s)).Select(s => $"Task waiting at:\n{s}"));
14261424
}
14271425

1428-
private void ApplyCompletionCommandReordering(
1426+
private void ApplyLegacyCompletionCommandReordering(
14291427
WorkflowActivation act,
14301428
WorkflowActivationCompletion completion,
14311429
out bool workflowComplete)
14321430
{
1433-
// In earlier versions of the SDK we allowed commands to be sent after workflow
1434-
// completion. These ended up being removed effectively making the result of the
1435-
// workflow function mean any other later coroutine commands be ignored. To match
1436-
// Go/Java, we are now going to move workflow completion to the end so that
1437-
// same-task-post-completion commands are still accounted for.
1438-
//
1439-
// Note this only applies for successful activations that don't have completion
1440-
// reordering disabled and that are either not replaying or have the flag set.
1441-
1442-
// Find the index of the completion command
1443-
var completionCommandIndex = -1;
1431+
// Find the index of the last completion command
1432+
var lastCompletionCommandIndex = -1;
14441433
if (completion.Successful != null)
14451434
{
14461435
for (var i = completion.Successful.Commands.Count - 1; i >= 0; i--)
@@ -1452,31 +1441,32 @@ private void ApplyCompletionCommandReordering(
14521441
cmd.ContinueAsNewWorkflowExecution != null ||
14531442
cmd.FailWorkflowExecution != null)
14541443
{
1455-
completionCommandIndex = i;
1444+
lastCompletionCommandIndex = i;
14561445
break;
14571446
}
14581447
}
14591448
}
1460-
workflowComplete = completionCommandIndex >= 0;
1449+
workflowComplete = lastCompletionCommandIndex >= 0;
14611450

1462-
// This only applies for successful activations that have a completion not at the end,
1463-
// don't have completion reordering disabled, and that are either not replaying or have
1464-
// the flag set.
1451+
// In a previous version of .NET SDK, if this was a successful activation completion
1452+
// with a completion command not at the end, we'd reorder it to move at the end.
1453+
// However, this logic has now moved to core and become more robust. Therefore, we only
1454+
// apply this logic if we're replaying and flag is present so that workflows/histories
1455+
// that were created after this .NET flag but before the core flag still work.
14651456
if (completion.Successful == null ||
1466-
completionCommandIndex == -1 ||
1467-
completionCommandIndex == completion.Successful.Commands.Count - 1 ||
1468-
disableCompletionCommandReordering ||
1469-
(IsReplaying && !act.AvailableInternalFlags.Contains(
1470-
(uint)WorkflowLogicFlag.ReorderWorkflowCompletion)))
1457+
lastCompletionCommandIndex == -1 ||
1458+
lastCompletionCommandIndex == completion.Successful.Commands.Count - 1 ||
1459+
!IsReplaying ||
1460+
!act.AvailableInternalFlags.Contains((uint)WorkflowLogicFlag.ReorderWorkflowCompletion))
14711461
{
14721462
return;
14731463
}
14741464

1475-
// Now we know the completion is in the wrong spot and we're on a newer SDK, so set the
1476-
// SDK flag and move it
1465+
// Now we know that we're replaying w/ the flag set and the completion in the wrong
1466+
// spot, so set the SDK flag and move it
14771467
completion.Successful.UsedInternalFlags.Add((uint)WorkflowLogicFlag.ReorderWorkflowCompletion);
1478-
var compCmd = completion.Successful.Commands[completionCommandIndex];
1479-
completion.Successful.Commands.RemoveAt(completionCommandIndex);
1468+
var compCmd = completion.Successful.Commands[lastCompletionCommandIndex];
1469+
completion.Successful.Commands.RemoveAt(lastCompletionCommandIndex);
14801470
completion.Successful.Commands.Insert(completion.Successful.Commands.Count, compCmd);
14811471
}
14821472

src/Temporalio/Worker/WorkflowInstanceDetails.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@ namespace Temporalio.Worker
2626
/// <param name="OnTaskCompleted">Callback for every instance task complete.</param>
2727
/// <param name="RuntimeMetricMeter">Lazy runtime-level metric meter.</param>
2828
/// <param name="WorkerLevelFailureExceptionTypes">Failure exception types at worker level.</param>
29-
/// <param name="DisableCompletionCommandReordering">
30-
/// Whether to disable completion command reordering.
31-
/// </param>
3229
internal record WorkflowInstanceDetails(
3330
string Namespace,
3431
string TaskQueue,
@@ -44,6 +41,5 @@ internal record WorkflowInstanceDetails(
4441
Action<WorkflowInstance> OnTaskStarting,
4542
Action<WorkflowInstance, Exception?> OnTaskCompleted,
4643
Lazy<MetricMeter> RuntimeMetricMeter,
47-
IReadOnlyCollection<Type>? WorkerLevelFailureExceptionTypes,
48-
bool DisableCompletionCommandReordering);
44+
IReadOnlyCollection<Type>? WorkerLevelFailureExceptionTypes);
4945
}

src/Temporalio/Worker/WorkflowReplayer.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,7 @@ public WorkflowHistoryRunner(WorkflowReplayerOptions options, bool throwOnReplay
173173
OnTaskStarting: options.OnTaskStarting,
174174
OnTaskCompleted: options.OnTaskCompleted,
175175
RuntimeMetricMeter: new(() => runtime.MetricMeter),
176-
WorkerLevelFailureExceptionTypes: options.WorkflowFailureExceptionTypes,
177-
DisableCompletionCommandReordering: options.DisableWorkflowCompletionCommandReordering),
176+
WorkerLevelFailureExceptionTypes: options.WorkflowFailureExceptionTypes),
178177
(runId, removeFromCache) => SetResult(removeFromCache));
179178
}
180179
catch

src/Temporalio/Worker/WorkflowReplayerOptions.cs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -128,15 +128,6 @@ public class WorkflowReplayerOptions : ICloneable
128128
internal Func<WorkflowInstanceDetails, IWorkflowInstance> WorkflowInstanceFactory { get; set; } =
129129
TemporalWorkerOptions.DefaultWorkflowInstanceFactory;
130130

131-
/// <summary>
132-
/// Gets or sets a value indicating whether the workflow completion command reordering will
133-
/// apply.
134-
/// </summary>
135-
/// <remarks>
136-
/// This is visible for testing only.
137-
/// </remarks>
138-
internal bool DisableWorkflowCompletionCommandReordering { get; set; }
139-
140131
/// <summary>
141132
/// Add the given type as a workflow.
142133
/// </summary>

src/Temporalio/Worker/WorkflowWorker.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,7 @@ private IWorkflowInstance CreateInstance(WorkflowActivation act)
283283
OnTaskStarting: options.OnTaskStarting,
284284
OnTaskCompleted: options.OnTaskCompleted,
285285
RuntimeMetricMeter: options.RuntimeMetricMeter,
286-
WorkerLevelFailureExceptionTypes: options.WorkerLevelFailureExceptionTypes,
287-
DisableCompletionCommandReordering: options.DisableCompletionCommandReordering));
286+
WorkerLevelFailureExceptionTypes: options.WorkerLevelFailureExceptionTypes));
288287
}
289288
}
290289
}

src/Temporalio/Worker/WorkflowWorkerOptions.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,5 @@ internal record WorkflowWorkerOptions(
2121
Action<WorkflowInstance> OnTaskStarting,
2222
Action<WorkflowInstance, Exception?> OnTaskCompleted,
2323
Lazy<MetricMeter> RuntimeMetricMeter,
24-
IReadOnlyCollection<Type>? WorkerLevelFailureExceptionTypes,
25-
bool DisableCompletionCommandReordering);
24+
IReadOnlyCollection<Type>? WorkerLevelFailureExceptionTypes);
2625
}

0 commit comments

Comments
 (0)