From cc6ab214b49d4f2cd025239353e6a322f56795a5 Mon Sep 17 00:00:00 2001 From: Thomas Hardy Date: Tue, 31 Mar 2026 15:03:11 -0700 Subject: [PATCH] fix assignment of typed search attributes on CaN and child workflows --- src/Temporalio/Worker/WorkflowInstance.cs | 4 +- .../Worker/WorkflowWorkerTests.cs | 85 +++++++++++++++++++ 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/src/Temporalio/Worker/WorkflowInstance.cs b/src/Temporalio/Worker/WorkflowInstance.cs index d358ac98..1043450c 100644 --- a/src/Temporalio/Worker/WorkflowInstance.cs +++ b/src/Temporalio/Worker/WorkflowInstance.cs @@ -1015,7 +1015,7 @@ private async Task RunTopLevelAsync(Func func) } if (e.Input.Options?.TypedSearchAttributes is SearchAttributeCollection attrs) { - cmd.SearchAttributes.IndexedFields.Add(attrs.ToProto().IndexedFields); + cmd.SearchAttributes = attrs.ToProto(); } if (e.Input.Headers is IDictionary headers) { @@ -2420,7 +2420,7 @@ public override Task> StartChildWorkflow } if (input.Options?.TypedSearchAttributes is SearchAttributeCollection attrs) { - cmd.SearchAttributes.IndexedFields.Add(attrs.ToProto().IndexedFields); + cmd.SearchAttributes = attrs.ToProto(); } if (input.Headers is IDictionary headers) { diff --git a/tests/Temporalio.Tests/Worker/WorkflowWorkerTests.cs b/tests/Temporalio.Tests/Worker/WorkflowWorkerTests.cs index 4a5e994f..7cd6c3a9 100644 --- a/tests/Temporalio.Tests/Worker/WorkflowWorkerTests.cs +++ b/tests/Temporalio.Tests/Worker/WorkflowWorkerTests.cs @@ -1518,6 +1518,52 @@ await AssertMore.EventuallyAsync(async () => }); } + [Workflow] + public class ChildWorkflowSearchAttributesWorkflow + { + [Workflow] + public class ChildWorkflow + { + [WorkflowRun] + public Task RunAsync() => Workflow.DelayAsync(Timeout.Infinite); + } + + [WorkflowRun] + public async Task RunAsync() + { + var attrs = new SearchAttributeCollection.Builder() + .Set(AttrKeyword, "child-keyword") + .ToSearchAttributeCollection(); + + var childHandle = await Workflow.StartChildWorkflowAsync( + (ChildWorkflow wf) => wf.RunAsync(), + new() { TypedSearchAttributes = attrs }); + + return childHandle.Id; + } + } + + [Fact] + public async Task ExecuteWorkflowAsync_ChildWorkflowSearchAttributes_SetProperly() + { + await EnsureSearchAttributesPresentAsync(); + await ExecuteWorkerAsync( + async worker => + { + var handle = await Env.Client.StartWorkflowAsync( + (ChildWorkflowSearchAttributesWorkflow wf) => wf.RunAsync(), + new(id: $"workflow-{Guid.NewGuid()}", taskQueue: worker.Options.TaskQueue!) + { + ExecutionTimeout = TimeSpan.FromSeconds(5), + }); + var childId = await handle.GetResultAsync(); + var childDesc = await Env.Client.GetWorkflowHandle(childId).DescribeAsync(); + Assert.Equal("child-keyword", childDesc.TypedSearchAttributes.Get(AttrKeyword)); + }, + new TemporalWorkerOptions() + .AddWorkflow()); + } + [Workflow] public class MemoWorkflow { @@ -1643,6 +1689,45 @@ await ExecuteWorkerAsync(async worker => }); } + [Workflow] + public class ContinueAsNewSearchAttributesWorkflow + { + [WorkflowRun] + public async Task RunAsync(bool continued) + { + if (continued) + { + return; + } + throw Workflow.CreateContinueAsNewException( + (ContinueAsNewSearchAttributesWorkflow wf) => wf.RunAsync(true), + new() + { + TypedSearchAttributes = new SearchAttributeCollection.Builder() + .Set(AttrKeyword, "can-keyword") + .ToSearchAttributeCollection(), + }); + } + } + + [Fact] + public async Task ExecuteWorkflowAsync_ContinueAsNewSearchAttributes_SetProperly() + { + await EnsureSearchAttributesPresentAsync(); + await ExecuteWorkerAsync(async worker => + { + var handle = await Env.Client.StartWorkflowAsync( + (ContinueAsNewSearchAttributesWorkflow wf) => wf.RunAsync(false), + new(id: $"workflow-{Guid.NewGuid()}", taskQueue: worker.Options.TaskQueue!) + { + ExecutionTimeout = TimeSpan.FromSeconds(5), + }); + await handle.GetResultAsync(); + var desc = await handle.DescribeAsync(); + Assert.Equal("can-keyword", desc.TypedSearchAttributes.Get(AttrKeyword)); + }); + } + [Workflow] public class SimpleActivityWorkflow {