From 7683b677c89dbf9155631f118fa33ea5c815b30d Mon Sep 17 00:00:00 2001
From: jmaeagle99 <44687433+jmaeagle99@users.noreply.github.com>
Date: Thu, 21 May 2026 14:10:22 -0700
Subject: [PATCH 1/8] test: enable draining worker pollers on shutdown
---
tests/Temporalio.Tests/WorkflowEnvironment.cs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tests/Temporalio.Tests/WorkflowEnvironment.cs b/tests/Temporalio.Tests/WorkflowEnvironment.cs
index 065b9adc..6a9c5abb 100644
--- a/tests/Temporalio.Tests/WorkflowEnvironment.cs
+++ b/tests/Temporalio.Tests/WorkflowEnvironment.cs
@@ -99,6 +99,9 @@ public async Task InitializeAsync()
// Enable Nexus cancellation types
"--dynamic-config-value",
"component.nexusoperations.recordCancelRequestCompletionEvents=true",
+ // Enable draining worker pollers on shutdown
+ "--dynamic-config-value",
+ "frontend.enableCancelWorkerPollsOnShutdown=true",
},
},
});
From 896d212a01cd06d21032bd4e89b6c36db7738951 Mon Sep 17 00:00:00 2001
From: jmaeagle99 <44687433+jmaeagle99@users.noreply.github.com>
Date: Fri, 22 May 2026 15:59:51 -0700
Subject: [PATCH 2/8] Update sdk-core to latest
---
src/Temporalio/Bridge/sdk-core | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Temporalio/Bridge/sdk-core b/src/Temporalio/Bridge/sdk-core
index a0ad8769..6cb67686 160000
--- a/src/Temporalio/Bridge/sdk-core
+++ b/src/Temporalio/Bridge/sdk-core
@@ -1 +1 @@
-Subproject commit a0ad8769d99a4432594d102efebb527d4bf5328f
+Subproject commit 6cb67686dcb5c8fc53e912f15c4b2072fb586e31
From 1da3150e41ead7fb6631c2bf81b4e516d3c60c83 Mon Sep 17 00:00:00 2001
From: jmaeagle99 <44687433+jmaeagle99@users.noreply.github.com>
Date: Fri, 22 May 2026 16:20:11 -0700
Subject: [PATCH 3/8] Regenerate Temporal API
---
.../Api/Cloud/ConnectivityRule/V1/Message.cs | 60 ++++++++++++++++---
1 file changed, 51 insertions(+), 9 deletions(-)
diff --git a/src/Temporalio/Api/Cloud/ConnectivityRule/V1/Message.cs b/src/Temporalio/Api/Cloud/ConnectivityRule/V1/Message.cs
index 10c04a2f..c3c74308 100644
--- a/src/Temporalio/Api/Cloud/ConnectivityRule/V1/Message.cs
+++ b/src/Temporalio/Api/Cloud/ConnectivityRule/V1/Message.cs
@@ -39,20 +39,21 @@ static MessageReflection() {
"MS5QdWJsaWNDb25uZWN0aXZpdHlSdWxlSAASVwoMcHJpdmF0ZV9ydWxlGAIg",
"ASgLMj8udGVtcG9yYWwuYXBpLmNsb3VkLmNvbm5lY3Rpdml0eXJ1bGUudjEu",
"UHJpdmF0ZUNvbm5lY3Rpdml0eVJ1bGVIAEIRCg9jb25uZWN0aW9uX3R5cGUi",
- "GAoWUHVibGljQ29ubmVjdGl2aXR5UnVsZSJeChdQcml2YXRlQ29ubmVjdGl2",
- "aXR5UnVsZRIVCg1jb25uZWN0aW9uX2lkGAEgASgJEhYKDmdjcF9wcm9qZWN0",
- "X2lkGAIgASgJEg4KBnJlZ2lvbhgDIAEoCUoECAQQBULUAQopaW8udGVtcG9y",
- "YWwuYXBpLmNsb3VkLmNvbm5lY3Rpdml0eXJ1bGUudjFCDE1lc3NhZ2VQcm90",
- "b1ABWj1nby50ZW1wb3JhbC5pby9hcGkvY2xvdWQvY29ubmVjdGl2aXR5cnVs",
- "ZS92MTtjb25uZWN0aXZpdHlydWxlqgIoVGVtcG9yYWxpby5BcGkuQ2xvdWQu",
- "Q29ubmVjdGl2aXR5UnVsZS5WMeoCLFRlbXBvcmFsaW86OkFwaTo6Q2xvdWQ6",
- "OkNvbm5lY3Rpdml0eVJ1bGU6OlYxYgZwcm90bzM="));
+ "MwoWUHVibGljQ29ubmVjdGl2aXR5UnVsZRIZChFlbmFibGVfc3RhYmxlX2lw",
+ "cxgBIAEoCCJeChdQcml2YXRlQ29ubmVjdGl2aXR5UnVsZRIVCg1jb25uZWN0",
+ "aW9uX2lkGAEgASgJEhYKDmdjcF9wcm9qZWN0X2lkGAIgASgJEg4KBnJlZ2lv",
+ "bhgDIAEoCUoECAQQBULUAQopaW8udGVtcG9yYWwuYXBpLmNsb3VkLmNvbm5l",
+ "Y3Rpdml0eXJ1bGUudjFCDE1lc3NhZ2VQcm90b1ABWj1nby50ZW1wb3JhbC5p",
+ "by9hcGkvY2xvdWQvY29ubmVjdGl2aXR5cnVsZS92MTtjb25uZWN0aXZpdHly",
+ "dWxlqgIoVGVtcG9yYWxpby5BcGkuQ2xvdWQuQ29ubmVjdGl2aXR5UnVsZS5W",
+ "MeoCLFRlbXBvcmFsaW86OkFwaTo6Q2xvdWQ6OkNvbm5lY3Rpdml0eVJ1bGU6",
+ "OlYxYgZwcm90bzM="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Temporalio.Api.Cloud.Resource.V1.MessageReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor, },
new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
new pbr::GeneratedClrTypeInfo(typeof(global::Temporalio.Api.Cloud.ConnectivityRule.V1.ConnectivityRule), global::Temporalio.Api.Cloud.ConnectivityRule.V1.ConnectivityRule.Parser, new[]{ "Id", "Spec", "ResourceVersion", "State", "AsyncOperationId", "CreatedTime" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Temporalio.Api.Cloud.ConnectivityRule.V1.ConnectivityRuleSpec), global::Temporalio.Api.Cloud.ConnectivityRule.V1.ConnectivityRuleSpec.Parser, new[]{ "PublicRule", "PrivateRule" }, new[]{ "ConnectionType" }, null, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Temporalio.Api.Cloud.ConnectivityRule.V1.PublicConnectivityRule), global::Temporalio.Api.Cloud.ConnectivityRule.V1.PublicConnectivityRule.Parser, null, null, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Temporalio.Api.Cloud.ConnectivityRule.V1.PublicConnectivityRule), global::Temporalio.Api.Cloud.ConnectivityRule.V1.PublicConnectivityRule.Parser, new[]{ "EnableStableIps" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Temporalio.Api.Cloud.ConnectivityRule.V1.PrivateConnectivityRule), global::Temporalio.Api.Cloud.ConnectivityRule.V1.PrivateConnectivityRule.Parser, new[]{ "ConnectionId", "GcpProjectId", "Region" }, null, null, null, null)
}));
}
@@ -799,6 +800,7 @@ public PublicConnectivityRule() {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public PublicConnectivityRule(PublicConnectivityRule other) : this() {
+ enableStableIps_ = other.enableStableIps_;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
@@ -808,6 +810,22 @@ public PublicConnectivityRule Clone() {
return new PublicConnectivityRule(this);
}
+ /// Field number for the "enable_stable_ips" field.
+ public const int EnableStableIpsFieldNumber = 1;
+ private bool enableStableIps_;
+ ///
+ /// Flag to determine namespace is connected via a predictable set of IPs on public internet
+ /// temporal:versioning:min_version=v0.15.0
+ ///
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
+ public bool EnableStableIps {
+ get { return enableStableIps_; }
+ set {
+ enableStableIps_ = value;
+ }
+ }
+
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public override bool Equals(object other) {
@@ -823,6 +841,7 @@ public bool Equals(PublicConnectivityRule other) {
if (ReferenceEquals(other, this)) {
return true;
}
+ if (EnableStableIps != other.EnableStableIps) return false;
return Equals(_unknownFields, other._unknownFields);
}
@@ -830,6 +849,7 @@ public bool Equals(PublicConnectivityRule other) {
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public override int GetHashCode() {
int hash = 1;
+ if (EnableStableIps != false) hash ^= EnableStableIps.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
@@ -848,6 +868,10 @@ public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
+ if (EnableStableIps != false) {
+ output.WriteRawTag(8);
+ output.WriteBool(EnableStableIps);
+ }
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
@@ -858,6 +882,10 @@ public void WriteTo(pb::CodedOutputStream output) {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
+ if (EnableStableIps != false) {
+ output.WriteRawTag(8);
+ output.WriteBool(EnableStableIps);
+ }
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
@@ -868,6 +896,9 @@ public void WriteTo(pb::CodedOutputStream output) {
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public int CalculateSize() {
int size = 0;
+ if (EnableStableIps != false) {
+ size += 1 + 1;
+ }
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
@@ -880,6 +911,9 @@ public void MergeFrom(PublicConnectivityRule other) {
if (other == null) {
return;
}
+ if (other.EnableStableIps != false) {
+ EnableStableIps = other.EnableStableIps;
+ }
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
@@ -895,6 +929,10 @@ public void MergeFrom(pb::CodedInputStream input) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
+ case 8: {
+ EnableStableIps = input.ReadBool();
+ break;
+ }
}
}
#endif
@@ -910,6 +948,10 @@ public void MergeFrom(pb::CodedInputStream input) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
break;
+ case 8: {
+ EnableStableIps = input.ReadBool();
+ break;
+ }
}
}
}
From 05ef58adc43e87a4bfb2d5f1c1f3a3a9bcc64a15 Mon Sep 17 00:00:00 2001
From: jmaeagle99 <44687433+jmaeagle99@users.noreply.github.com>
Date: Fri, 22 May 2026 16:51:09 -0700
Subject: [PATCH 4/8] Update sdk-core to latest
---
src/Temporalio/Bridge/sdk-core | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Temporalio/Bridge/sdk-core b/src/Temporalio/Bridge/sdk-core
index 6cb67686..6d651791 160000
--- a/src/Temporalio/Bridge/sdk-core
+++ b/src/Temporalio/Bridge/sdk-core
@@ -1 +1 @@
-Subproject commit 6cb67686dcb5c8fc53e912f15c4b2072fb586e31
+Subproject commit 6d65179136cddd31f49f9c4f2427dcc6ceb0f932
From d15f3c78edeceb88ae40c0e70dad689f6e9e12d5 Mon Sep 17 00:00:00 2001
From: jmaeagle99 <44687433+jmaeagle99@users.noreply.github.com>
Date: Tue, 26 May 2026 10:12:28 -0700
Subject: [PATCH 5/8] fix(test): fix test to terminate deadlocked workflow
---
.../Temporalio.Tests/Worker/WorkflowWorkerTests.cs | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/tests/Temporalio.Tests/Worker/WorkflowWorkerTests.cs b/tests/Temporalio.Tests/Worker/WorkflowWorkerTests.cs
index b342b8e9..da6a5b05 100644
--- a/tests/Temporalio.Tests/Worker/WorkflowWorkerTests.cs
+++ b/tests/Temporalio.Tests/Worker/WorkflowWorkerTests.cs
@@ -5434,9 +5434,16 @@ await AssertMore.HasEventEventuallyAsync(
return "never-reached";
}))));
- // Wait for deadlock, ignore the hanging worker
- await AssertTaskFailureContainsEventuallyAsync(
- await handleCompletion.Task, "deadlocked");
+ // Wait for deadlock, then terminate the workflow to avoid preventing the worker from shutting down.
+ var handle = await handleCompletion.Task;
+ try
+ {
+ await AssertTaskFailureContainsEventuallyAsync(handle, "deadlocked");
+ }
+ finally
+ {
+ await handle.TerminateAsync();
+ }
}
// Run the three deadlocking scenarios concurrently since they are slow
From fa345b92f90e6fe40877b8df4abc825da85f7192 Mon Sep 17 00:00:00 2001
From: jmaeagle99 <44687433+jmaeagle99@users.noreply.github.com>
Date: Tue, 26 May 2026 13:33:29 -0700
Subject: [PATCH 6/8] fix(test): use Temporalio.Tests.WorkflowEnviroment to
pick up common environment settings
---
tests/Temporalio.Tests/Worker/WorkflowWorkerTests.cs | 3 ++-
tests/Temporalio.Tests/WorkflowEnvironment.cs | 8 +++++---
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/tests/Temporalio.Tests/Worker/WorkflowWorkerTests.cs b/tests/Temporalio.Tests/Worker/WorkflowWorkerTests.cs
index da6a5b05..c3eeea25 100644
--- a/tests/Temporalio.Tests/Worker/WorkflowWorkerTests.cs
+++ b/tests/Temporalio.Tests/Worker/WorkflowWorkerTests.cs
@@ -4848,7 +4848,8 @@ public async Task ExecuteWorkflowAsync_WorkerClientReplacement_UsesNewClient()
// We are going to create a second ephemeral server and start a workflow on each server.
// The worker will start with a client on the first, then we'll swap the clients, signal
// both workflows, and confirm the second workflow completes as expected.
- await using var otherEnv = await Temporalio.Testing.WorkflowEnvironment.StartLocalAsync();
+ await using var otherEnv = new WorkflowEnvironment();
+ await otherEnv.InitializeAsync();
// Start both workflows on different servers
var taskQueue = $"tq-{Guid.NewGuid()}";
diff --git a/tests/Temporalio.Tests/WorkflowEnvironment.cs b/tests/Temporalio.Tests/WorkflowEnvironment.cs
index 6a9c5abb..14b34bcf 100644
--- a/tests/Temporalio.Tests/WorkflowEnvironment.cs
+++ b/tests/Temporalio.Tests/WorkflowEnvironment.cs
@@ -8,7 +8,7 @@ namespace Temporalio.Tests;
using Temporalio.Worker;
using Xunit;
-public class WorkflowEnvironment : IAsyncLifetime
+public sealed class WorkflowEnvironment : IAsyncLifetime, IAsyncDisposable
{
public const int ContinueAsNewSuggestedHistoryCount = 50;
@@ -108,7 +108,7 @@ public async Task InitializeAsync()
}
}
- public async Task DisposeAsync()
+ public async ValueTask DisposeAsync()
{
try
{
@@ -126,11 +126,13 @@ public async Task DisposeAsync()
}
if (env != null)
{
- await env.ShutdownAsync();
+ await env.DisposeAsync();
}
}
}
+ Task IAsyncLifetime.DisposeAsync() => DisposeAsync().AsTask();
+
private KitchenSinkWorker StartKitchenSinkWorker()
{
var taskQueue = Guid.NewGuid().ToString();
From 42be7b6884cf78292d90467a9767cdc102ab321e Mon Sep 17 00:00:00 2001
From: jmaeagle99 <44687433+jmaeagle99@users.noreply.github.com>
Date: Tue, 26 May 2026 14:53:51 -0700
Subject: [PATCH 7/8] Update sdk-core to latest
---
src/Temporalio/Bridge/sdk-core | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Temporalio/Bridge/sdk-core b/src/Temporalio/Bridge/sdk-core
index 6d651791..866419a7 160000
--- a/src/Temporalio/Bridge/sdk-core
+++ b/src/Temporalio/Bridge/sdk-core
@@ -1 +1 @@
-Subproject commit 6d65179136cddd31f49f9c4f2427dcc6ceb0f932
+Subproject commit 866419a7062a9a9d3928aa32437f7acb5aeb2193
From 2fc89e69d6998de891e0ba061acd75f052325d31 Mon Sep 17 00:00:00 2001
From: jmaeagle99 <44687433+jmaeagle99@users.noreply.github.com>
Date: Tue, 26 May 2026 15:24:45 -0700
Subject: [PATCH 8/8] fix(proto): Update proto directory
---
src/Temporalio.Api.Generator/Program.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Temporalio.Api.Generator/Program.cs b/src/Temporalio.Api.Generator/Program.cs
index ada8f746..2f45a74d 100644
--- a/src/Temporalio.Api.Generator/Program.cs
+++ b/src/Temporalio.Api.Generator/Program.cs
@@ -4,7 +4,7 @@
var currFile = new StackTrace(true).GetFrame(0)?.GetFileName();
var projectDir = Path.GetFullPath(Path.Join(currFile, "../../../"));
-var protoDir = Path.Join(projectDir, "src/Temporalio/Bridge/sdk-core/crates/common/protos");
+var protoDir = Path.Join(projectDir, "src/Temporalio/Bridge/sdk-core/crates/protos/protos");
var apiProtoDir = Path.Join(protoDir, "api_upstream");
var apiCloudProtoDir = Path.Join(protoDir, "api_cloud_upstream");
var testSrvProtoDir = Path.Join(protoDir, "testsrv_upstream");