From 62da5d6447c1d1ec88a191144fb598e20bf6193b Mon Sep 17 00:00:00 2001 From: Spencer Judge Date: Mon, 5 Aug 2024 15:33:41 -0700 Subject: [PATCH] Add workflow id conflict policy to signal with start (#322) --- .../Client/TemporalClient.Workflow.cs | 1 + .../Worker/WorkflowWorkerTests.cs | 41 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/Temporalio/Client/TemporalClient.Workflow.cs b/src/Temporalio/Client/TemporalClient.Workflow.cs index 8c4d08e0..95eb5055 100644 --- a/src/Temporalio/Client/TemporalClient.Workflow.cs +++ b/src/Temporalio/Client/TemporalClient.Workflow.cs @@ -607,6 +607,7 @@ private async Task> StartWorkflowInternalAsyn Header = req.Header, WorkflowStartDelay = req.WorkflowStartDelay, SignalName = input.Options.StartSignal, + WorkflowIdConflictPolicy = input.Options.IdConflictPolicy, }; if (input.Options.StartSignalArgs != null && input.Options.StartSignalArgs.Count > 0) { diff --git a/tests/Temporalio.Tests/Worker/WorkflowWorkerTests.cs b/tests/Temporalio.Tests/Worker/WorkflowWorkerTests.cs index 5f63e211..8de302d9 100644 --- a/tests/Temporalio.Tests/Worker/WorkflowWorkerTests.cs +++ b/tests/Temporalio.Tests/Worker/WorkflowWorkerTests.cs @@ -5618,9 +5618,20 @@ await AssertWarnings( [Workflow] public class IdConflictWorkflow { + private string signal = "nothing"; + // Just wait forever [WorkflowRun] public Task RunAsync() => Workflow.WaitConditionAsync(() => false); + + [WorkflowSignal] + public async Task TheSignal(string sig) + { + signal = sig; + } + + [WorkflowQuery] + public string GetSignal() => signal; } [Fact] @@ -5648,6 +5659,7 @@ await Assert.ThrowsAsync(() => { IdConflictPolicy = WorkflowIdConflictPolicy.Fail, })); + // signal-with-start does not allow fail policy // Confirm gives back same handle if requested var newHandle = await Env.Client.StartWorkflowAsync( @@ -5660,6 +5672,19 @@ await Assert.ThrowsAsync(() => Assert.Equal(handle.RunId, newHandle.RunId); Assert.Equal(WorkflowExecutionStatus.Running, (await handle.DescribeAsync()).Status); Assert.Equal(WorkflowExecutionStatus.Running, (await newHandle.DescribeAsync()).Status); + // Also with signal-with-start + newHandle = await Env.Client.StartWorkflowAsync( + (IdConflictWorkflow wf) => wf.RunAsync(), + new(id: handle.Id, taskQueue: worker.Options.TaskQueue!) + { + StartSignal = "TheSignal", + StartSignalArgs = new[] { "hi!" }, + IdConflictPolicy = WorkflowIdConflictPolicy.UseExisting, + }); + newHandle = newHandle with { RunId = newHandle.ResultRunId }; + Assert.Equal(handle.RunId, newHandle.RunId); + Assert.Equal(WorkflowExecutionStatus.Running, (await handle.DescribeAsync()).Status); + Assert.Equal(WorkflowExecutionStatus.Running, (await newHandle.DescribeAsync()).Status); // Confirm terminates and starts new if requested newHandle = await Env.Client.StartWorkflowAsync( @@ -5672,6 +5697,22 @@ await Assert.ThrowsAsync(() => Assert.NotEqual(handle.RunId, newHandle.RunId); Assert.Equal(WorkflowExecutionStatus.Terminated, (await handle.DescribeAsync()).Status); Assert.Equal(WorkflowExecutionStatus.Running, (await newHandle.DescribeAsync()).Status); + // Also with signal-with-start + newHandle = await Env.Client.StartWorkflowAsync( + (IdConflictWorkflow wf) => wf.RunAsync(), + new(id: handle.Id, taskQueue: worker.Options.TaskQueue!) + { + StartSignal = "TheSignal", + StartSignalArgs = new[] { "hi!" }, + IdConflictPolicy = WorkflowIdConflictPolicy.TerminateExisting, + }); + newHandle = newHandle with { RunId = newHandle.ResultRunId }; + Assert.NotEqual(handle.RunId, newHandle.RunId); + Assert.Equal(WorkflowExecutionStatus.Terminated, (await handle.DescribeAsync()).Status); + Assert.Equal(WorkflowExecutionStatus.Running, (await newHandle.DescribeAsync()).Status); + // Ensure it actually got the signal this time + var queryRes = await newHandle.QueryAsync(wf => wf.GetSignal()); + Assert.Equal("hi!", queryRes); }); }