diff --git a/Directory.Packages.props b/Directory.Packages.props
index f8a422af..5ab0ff95 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -31,7 +31,7 @@
-
+
diff --git a/src/Worker/Core/Shims/TaskOrchestrationContextWrapper.cs b/src/Worker/Core/Shims/TaskOrchestrationContextWrapper.cs
index 945d6ac5..98ba2721 100644
--- a/src/Worker/Core/Shims/TaskOrchestrationContextWrapper.cs
+++ b/src/Worker/Core/Shims/TaskOrchestrationContextWrapper.cs
@@ -226,7 +226,8 @@ public override async Task CallSubOrchestratorAsync(
version,
instanceId,
policy.ToDurableTaskCoreRetryOptions(),
- input);
+ input,
+ options.Tags);
}
else if (options?.Retry?.Handler is AsyncRetryHandler handler)
{
diff --git a/test/Grpc.IntegrationTests/OrchestrationPatterns.cs b/test/Grpc.IntegrationTests/OrchestrationPatterns.cs
index d52c271c..1114029b 100644
--- a/test/Grpc.IntegrationTests/OrchestrationPatterns.cs
+++ b/test/Grpc.IntegrationTests/OrchestrationPatterns.cs
@@ -59,7 +59,6 @@ public async Task ScheduleOrchestrationWithTags()
instanceId, this.TimeoutToken);
Assert.NotNull(metadata);
- Assert.Equal(instanceId, metadata.InstanceId);
Assert.Equal(OrchestrationRuntimeStatus.Completed, metadata.RuntimeStatus);
Assert.NotNull(metadata.Tags);
Assert.Equal(2, metadata.Tags.Count);
@@ -105,7 +104,6 @@ public async Task ScheduleSubOrchestrationWithTags()
subOrchestrationOptions.InstanceId, this.TimeoutToken);
Assert.NotNull(metadata);
- Assert.Equal(subOrchestrationOptions.InstanceId, metadata.InstanceId);
Assert.Equal(OrchestrationRuntimeStatus.Completed, metadata.RuntimeStatus);
Assert.NotNull(metadata.Tags);
Assert.Equal(2, metadata.Tags.Count);
@@ -113,6 +111,66 @@ public async Task ScheduleSubOrchestrationWithTags()
Assert.Equal("value2", metadata.Tags["tag2"]);
}
+ [Fact]
+ public async Task ScheduleSubOrchestrationWithTagsAndRetryPolicy()
+ {
+ TaskName orchestratorName = nameof(ScheduleSubOrchestrationWithTagsAndRetryPolicy);
+
+ // Schedule a new orchestration instance with tags and a retry policy
+ SubOrchestrationOptions subOrchestrationOptions = new()
+ {
+ InstanceId = "instance_id",
+ Tags = new Dictionary
+ {
+ { "tag1", "value1" },
+ { "tag2", "value2" }
+ },
+ Retry = new RetryPolicy(maxNumberOfAttempts: 2, firstRetryInterval: TimeSpan.FromMilliseconds(500))
+ };
+
+ int failCounter = 0;
+ int invocationCounter = 0;
+ await using HostTestLifetime server = await this.StartWorkerAsync(b =>
+ {
+ b.AddTasks(tasks => tasks.AddOrchestratorFunc(orchestratorName, async (ctx, input) =>
+ {
+ if (!ctx.IsReplaying)
+ {
+ invocationCounter++;
+ }
+ if (failCounter < 1 && input == 2)
+ {
+ failCounter++;
+ throw new Exception("Simulated failure");
+ }
+
+ int result = 1;
+ if (input < 2)
+ {
+ // recursively call this same orchestrator
+ result += await ctx.CallSubOrchestratorAsync(orchestratorName, input: input + 1, subOrchestrationOptions);
+ }
+
+ return result;
+ }));
+ });
+
+ await server.Client.ScheduleNewOrchestrationInstanceAsync(orchestratorName, input: 1);
+
+ // Confirm the orchestration eventually succeeded after some delay for the retry to complete
+ await Task.Delay(TimeSpan.FromSeconds(3));
+ OrchestrationMetadata metadata = await server.Client.WaitForInstanceCompletionAsync(
+ subOrchestrationOptions.InstanceId, this.TimeoutToken);
+ Assert.NotNull(metadata);
+ Assert.Equal(OrchestrationRuntimeStatus.Completed, metadata.RuntimeStatus);
+ Assert.NotNull(metadata.Tags);
+ Assert.Equal(2, metadata.Tags.Count);
+ Assert.Equal("value1", metadata.Tags["tag1"]);
+ Assert.Equal("value2", metadata.Tags["tag2"]);
+ // 3 invocations - one for the parent orchestration, one for the first suborchestration attempt, one for the final suborchestration attempt
+ Assert.Equal(3, invocationCounter);
+ }
+
[Fact]
public async Task SingleTimer()
{