From 526c9a2b570d1eb4cfbbb23ca07f638be7bf8060 Mon Sep 17 00:00:00 2001 From: Andrew Yuan Date: Tue, 9 Dec 2025 10:58:20 -0500 Subject: [PATCH 1/5] add comments --- temporal/api/workflowservice/v1/request_response.proto | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index 69b673c81..a8d8ac9d8 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -999,10 +999,15 @@ message ResetStickyTaskQueueResponse { message ShutdownWorkerRequest { string namespace = 1; + // sticky_task_queue may not always be populated. We want to ensure all workers + // send a shutdown request to update worker state for heartbeating, as well + // as cancel pending poll calls early, instead of waiting for timeouts. string sticky_task_queue = 2; string identity = 3; string reason = 4; + // WorkerHeartbeat contains a list of Worker Instance Keys for all workers + // that are shutting down. temporal.api.worker.v1.WorkerHeartbeat worker_heartbeat = 5; } From eb9b3215b2c50d89ffcf04dc327d321ec1e1da39 Mon Sep 17 00:00:00 2001 From: Andrew Yuan Date: Wed, 10 Dec 2025 12:45:47 -0500 Subject: [PATCH 2/5] Add new worker_instance_key field --- temporal/api/workflowservice/v1/request_response.proto | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index a8d8ac9d8..ae29d8554 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -1005,10 +1005,11 @@ message ShutdownWorkerRequest { string sticky_task_queue = 2; string identity = 3; string reason = 4; - - // WorkerHeartbeat contains a list of Worker Instance Keys for all workers - // that are shutting down. temporal.api.worker.v1.WorkerHeartbeat worker_heartbeat = 5; + // Technically this is also sent in the WorkerHeartbeat, but + // since worker heartbeating can be turned off, this needs + // to be a separate, top-level field. + string worker_instance_key = 6; } message ShutdownWorkerResponse { From b6c0b5352453e65fc7d12ea242e1109a37e9d035 Mon Sep 17 00:00:00 2001 From: Andrew Yuan Date: Thu, 22 Jan 2026 11:38:39 -0800 Subject: [PATCH 3/5] add worker_instance_key fields to poll calls --- temporal/api/workflowservice/v1/request_response.proto | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index ae29d8554..aba42496d 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -269,6 +269,8 @@ message PollWorkflowTaskQueueRequest { // Worker deployment options that user has set in the worker. // Experimental. Worker Deployments are experimental and might significantly change in the future. temporal.api.deployment.v1.WorkerDeploymentOptions deployment_options = 6; + // A unique key for this worker instance, used for tracking worker lifecycle. + string worker_instance_key = 7; } message PollWorkflowTaskQueueResponse { @@ -440,6 +442,8 @@ message PollActivityTaskQueueRequest { temporal.api.common.v1.WorkerVersionCapabilities worker_version_capabilities = 5 [deprecated = true]; // Worker deployment options that user has set in the worker. temporal.api.deployment.v1.WorkerDeploymentOptions deployment_options = 6; + // A unique key for this worker instance, used for tracking worker lifecycle. + string worker_instance_key = 7; } message PollActivityTaskQueueResponse { @@ -1767,6 +1771,8 @@ message PollWorkflowExecutionUpdateRequest { // Specifies client's intent to wait for Update results. // Omit to request a non-blocking poll. temporal.api.update.v1.WaitPolicy wait_policy = 4; + // A unique key for this worker instance, used for tracking worker lifecycle. + string worker_instance_key = 8; } message PollWorkflowExecutionUpdateResponse { @@ -1805,6 +1811,8 @@ message PollNexusTaskQueueRequest { // Worker info to be sent to the server. repeated temporal.api.worker.v1.WorkerHeartbeat worker_heartbeat = 7; + // A unique key for this worker instance, used for tracking worker lifecycle. + string worker_instance_key = 8; } message PollNexusTaskQueueResponse { From cbebe7a65bd45af0b9a417109bf8be69336349b5 Mon Sep 17 00:00:00 2001 From: Andrew Yuan Date: Fri, 23 Jan 2026 09:20:58 -0800 Subject: [PATCH 4/5] Add task queue name and type --- temporal/api/workflowservice/v1/request_response.proto | 2 ++ 1 file changed, 2 insertions(+) diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index aba42496d..37a4d3056 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -1014,6 +1014,8 @@ message ShutdownWorkerRequest { // since worker heartbeating can be turned off, this needs // to be a separate, top-level field. string worker_instance_key = 6; + string task_queue = 7; + repeated temporal.api.enums.v1.TaskQueueType task_queue_types = 8; } message ShutdownWorkerResponse { From fcb16dd6943dd7d4eee6862cab10896edc886c3f Mon Sep 17 00:00:00 2001 From: Andrew Yuan Date: Fri, 23 Jan 2026 12:28:24 -0800 Subject: [PATCH 5/5] PR feedback --- .../workflowservice/v1/request_response.proto | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index 37a4d3056..9b4963694 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -258,6 +258,9 @@ message PollWorkflowTaskQueueRequest { temporal.api.taskqueue.v1.TaskQueue task_queue = 2; // The identity of the worker/client who is polling this task queue string identity = 3; + // A unique key for this worker instance, used for tracking worker lifecycle. + // This is guaranteed to be unique, whereas identity is not guaranteed to be unique. + string worker_instance_key = 7; // Deprecated. Use deployment_options instead. // Each worker process should provide an ID unique to the specific set of code it is running // "checksum" in this field name isn't very accurate, it should be though of as an id. @@ -269,8 +272,6 @@ message PollWorkflowTaskQueueRequest { // Worker deployment options that user has set in the worker. // Experimental. Worker Deployments are experimental and might significantly change in the future. temporal.api.deployment.v1.WorkerDeploymentOptions deployment_options = 6; - // A unique key for this worker instance, used for tracking worker lifecycle. - string worker_instance_key = 7; } message PollWorkflowTaskQueueResponse { @@ -435,6 +436,9 @@ message PollActivityTaskQueueRequest { temporal.api.taskqueue.v1.TaskQueue task_queue = 2; // The identity of the worker/client string identity = 3; + // A unique key for this worker instance, used for tracking worker lifecycle. + // This is guaranteed to be unique, whereas identity is not guaranteed to be unique. + string worker_instance_key = 7; temporal.api.taskqueue.v1.TaskQueueMetadata task_queue_metadata = 4; // Information about this worker's build identifier and if it is choosing to use the versioning // feature. See the `WorkerVersionCapabilities` docstring for more. @@ -442,8 +446,6 @@ message PollActivityTaskQueueRequest { temporal.api.common.v1.WorkerVersionCapabilities worker_version_capabilities = 5 [deprecated = true]; // Worker deployment options that user has set in the worker. temporal.api.deployment.v1.WorkerDeploymentOptions deployment_options = 6; - // A unique key for this worker instance, used for tracking worker lifecycle. - string worker_instance_key = 7; } message PollActivityTaskQueueResponse { @@ -1014,7 +1016,12 @@ message ShutdownWorkerRequest { // since worker heartbeating can be turned off, this needs // to be a separate, top-level field. string worker_instance_key = 6; + // Task queue name the worker is polling on. This allows server to cancel + // all outstanding poll RPC calls from SDK. This avoids a race condition that + // can lead to tasks being lost. string task_queue = 7; + // Task queue types that help server cancel outstanding poll RPC + // calls from SDK. This avoids a race condition that can lead to tasks being lost. repeated temporal.api.enums.v1.TaskQueueType task_queue_types = 8; } @@ -1773,8 +1780,6 @@ message PollWorkflowExecutionUpdateRequest { // Specifies client's intent to wait for Update results. // Omit to request a non-blocking poll. temporal.api.update.v1.WaitPolicy wait_policy = 4; - // A unique key for this worker instance, used for tracking worker lifecycle. - string worker_instance_key = 8; } message PollWorkflowExecutionUpdateResponse { @@ -1803,6 +1808,9 @@ message PollNexusTaskQueueRequest { string namespace = 1; // The identity of the client who initiated this request. string identity = 2; + // A unique key for this worker instance, used for tracking worker lifecycle. + // This is guaranteed to be unique, whereas identity is not guaranteed to be unique. + string worker_instance_key = 8; temporal.api.taskqueue.v1.TaskQueue task_queue = 3; // Information about this worker's build identifier and if it is choosing to use the versioning // feature. See the `WorkerVersionCapabilities` docstring for more. @@ -1813,8 +1821,6 @@ message PollNexusTaskQueueRequest { // Worker info to be sent to the server. repeated temporal.api.worker.v1.WorkerHeartbeat worker_heartbeat = 7; - // A unique key for this worker instance, used for tracking worker lifecycle. - string worker_instance_key = 8; } message PollNexusTaskQueueResponse {