diff --git a/openapi/openapiv2.json b/openapi/openapiv2.json index 85e36caa2..79d7c0c7d 100644 --- a/openapi/openapiv2.json +++ b/openapi/openapiv2.json @@ -2735,7 +2735,7 @@ }, { "name": "query", - "description": "`query` in ListWorkers is used to filter workers based on worker status info.\nThe following worker status attributes are expected are supported as part of the query:\n* WorkerInstanceKey\n* WorkerIdentity\n* HostName\n* TaskQueue\n* DeploymentName\n* BuildId\n* SdkName\n* SdkVersion\n* StartTime\n* LastHeartbeatTime\n* Status\nCurrently metrics are not supported as a part of ListWorkers query.", + "description": "`query` in ListWorkers is used to filter workers based on worker attributes.\nSupported attributes:\n* WorkerInstanceKey\n* WorkerIdentity\n* HostName\n* TaskQueue\n* DeploymentName\n* BuildId\n* SdkName\n* SdkVersion\n* StartTime\n* Status", "in": "query", "required": false, "type": "string" @@ -7235,7 +7235,7 @@ }, { "name": "query", - "description": "`query` in ListWorkers is used to filter workers based on worker status info.\nThe following worker status attributes are expected are supported as part of the query:\n* WorkerInstanceKey\n* WorkerIdentity\n* HostName\n* TaskQueue\n* DeploymentName\n* BuildId\n* SdkName\n* SdkVersion\n* StartTime\n* LastHeartbeatTime\n* Status\nCurrently metrics are not supported as a part of ListWorkers query.", + "description": "`query` in ListWorkers is used to filter workers based on worker attributes.\nSupported attributes:\n* WorkerInstanceKey\n* WorkerIdentity\n* HostName\n* TaskQueue\n* DeploymentName\n* BuildId\n* SdkName\n* SdkVersion\n* StartTime\n* Status", "in": "query", "required": false, "type": "string" @@ -12040,6 +12040,15 @@ } } }, + "v1DeclinedTargetVersionUpgrade": { + "type": "object", + "properties": { + "deploymentVersion": { + "$ref": "#/definitions/v1WorkerDeploymentVersion" + } + }, + "description": "Wrapper for a target deployment version that the SDK declined to upgrade to.\nSee declined_target_version_upgrade on WorkflowExecutionStartedEventAttributes." + }, "v1DeleteNexusEndpointResponse": { "type": "object" }, @@ -13429,7 +13438,16 @@ "items": { "type": "object", "$ref": "#/definitions/v1WorkerInfo" - } + }, + "description": "Deprecated: Use workers instead. This field returns full WorkerInfo which\nincludes expensive runtime metrics. We will stop populating this field in the future." + }, + "workers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1WorkerListInfo" + }, + "description": "Limited worker information." }, "nextPageToken": { "type": "string", @@ -13670,6 +13688,10 @@ "standaloneActivities": { "type": "boolean", "title": "True if the namespace supports standalone activities" + }, + "workerPollCompleteOnShutdown": { + "type": "boolean", + "description": "True if the namespace supports server-side completion of outstanding worker polls on shutdown.\nWhen enabled, the server will complete polls for workers that send WorkerInstanceKey in their\npoll requests and call ShutdownWorker with the same WorkerInstanceKey. The poll will return\nan empty response. When this flag is true, workers should allow polls to return gracefully\nrather than terminating any open polls on shutdown." } }, "description": "Namespace capability details. Should contain what features are enabled in a namespace." @@ -15860,6 +15882,15 @@ "v1StopBatchOperationResponse": { "type": "object" }, + "v1StorageDriverInfo": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "The type of the driver, required." + } + } + }, "v1StructuredCalendarSpec": { "type": "object", "properties": { @@ -16885,6 +16916,14 @@ "$ref": "#/definitions/v1PluginInfo" }, "description": "Plugins currently in use by this SDK." + }, + "drivers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1StorageDriverInfo" + }, + "description": "Storage drivers in use by this SDK." } }, "description": "Worker info message, contains information about the worker and its current state.\nAll information is provided by the worker itself." @@ -16923,7 +16962,72 @@ "workerHeartbeat": { "$ref": "#/definitions/v1WorkerHeartbeat" } - } + }, + "description": "Detailed worker information." + }, + "v1WorkerListInfo": { + "type": "object", + "properties": { + "workerInstanceKey": { + "type": "string", + "description": "Worker identifier, should be unique for the namespace.\nIt is distinct from worker identity, which is not necessarily namespace-unique." + }, + "workerIdentity": { + "type": "string", + "description": "Worker identity, set by the client, may not be unique.\nUsually host_name+(user group name)+process_id, but can be overwritten by the user." + }, + "taskQueue": { + "type": "string", + "description": "Task queue this worker is polling for tasks." + }, + "deploymentVersion": { + "$ref": "#/definitions/v1WorkerDeploymentVersion" + }, + "sdkName": { + "type": "string" + }, + "sdkVersion": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/v1WorkerStatus", + "description": "Worker status. Defined by SDK." + }, + "startTime": { + "type": "string", + "format": "date-time", + "title": "Worker start time.\nIt can be used to determine worker uptime. (current time - start time)" + }, + "hostName": { + "type": "string", + "description": "Worker host identifier." + }, + "workerGroupingKey": { + "type": "string", + "title": "Worker grouping identifier. A key to group workers that share the same client+namespace+process.\nThis will be used to build the worker command nexus task queue name:\n\"temporal-sys/worker-commands/{worker_grouping_key}\"" + }, + "processId": { + "type": "string", + "description": "Worker process identifier. This id only needs to be unique\nwithin one host (so using e.g. a unix pid would be appropriate)." + }, + "plugins": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1PluginInfo" + }, + "description": "Plugins currently in use by this SDK." + }, + "drivers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1StorageDriverInfo" + }, + "description": "Storage drivers in use by this SDK." + } + }, + "description": "Limited worker information returned in the list response.\nWhen adding fields here, ensure that it is also added to WorkerInfo (as it carries the full worker information)." }, "v1WorkerPollerInfo": { "type": "object", @@ -17624,6 +17728,10 @@ "eagerExecutionAccepted": { "type": "boolean", "description": "A boolean indicating whether the SDK has asked to eagerly execute the first workflow task for this workflow and\neager execution was accepted by the server.\nOnly populated by server with version >= 1.29.0." + }, + "declinedTargetVersionUpgrade": { + "$ref": "#/definitions/v1DeclinedTargetVersionUpgrade", + "description": "During a previous run of this workflow, the server may have notified the SDK\nthat the Target Worker Deployment Version changed, but the SDK declined to\nupgrade (e.g., by continuing-as-new with PINNED behavior). This field records\nthe target version that was declined.\n\nThis is a wrapper message to distinguish \"never declined\" (nil wrapper) from\n\"declined an unversioned target\" (non-nil wrapper with nil deployment_version).\n\nUsed internally by the server during continue-as-new and retry.\nShould not be read or interpreted by SDKs." } }, "title": "Always the first event in workflow history" diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index 058b71005..24c527682 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -2461,8 +2461,8 @@ paths: - name: query in: query description: |- - `query` in ListWorkers is used to filter workers based on worker status info. - The following worker status attributes are expected are supported as part of the query: + `query` in ListWorkers is used to filter workers based on worker attributes. + Supported attributes: * WorkerInstanceKey * WorkerIdentity * HostName @@ -2472,9 +2472,7 @@ paths: * SdkName * SdkVersion * StartTime - * LastHeartbeatTime * Status - Currently metrics are not supported as a part of ListWorkers query. schema: type: string responses: @@ -6496,8 +6494,8 @@ paths: - name: query in: query description: |- - `query` in ListWorkers is used to filter workers based on worker status info. - The following worker status attributes are expected are supported as part of the query: + `query` in ListWorkers is used to filter workers based on worker attributes. + Supported attributes: * WorkerInstanceKey * WorkerIdentity * HostName @@ -6507,9 +6505,7 @@ paths: * SdkName * SdkVersion * StartTime - * LastHeartbeatTime * Status - Currently metrics are not supported as a part of ListWorkers query. schema: type: string responses: @@ -9230,6 +9226,14 @@ components: data: type: string format: bytes + DeclinedTargetVersionUpgrade: + type: object + properties: + deploymentVersion: + $ref: '#/components/schemas/WorkerDeploymentVersion' + description: |- + Wrapper for a target deployment version that the SDK declined to upgrade to. + See declined_target_version_upgrade on WorkflowExecutionStartedEventAttributes. DeleteNexusEndpointResponse: type: object properties: {} @@ -10550,6 +10554,14 @@ components: type: array items: $ref: '#/components/schemas/WorkerInfo' + description: |- + Deprecated: Use workers instead. This field returns full WorkerInfo which + includes expensive runtime metrics. We will stop populating this field in the future. + workers: + type: array + items: + $ref: '#/components/schemas/WorkerListInfo' + description: Limited worker information. nextPageToken: type: string description: Next page token @@ -10744,6 +10756,14 @@ components: standaloneActivities: type: boolean description: True if the namespace supports standalone activities + workerPollCompleteOnShutdown: + type: boolean + description: |- + True if the namespace supports server-side completion of outstanding worker polls on shutdown. + When enabled, the server will complete polls for workers that send WorkerInstanceKey in their + poll requests and call ShutdownWorker with the same WorkerInstanceKey. The poll will return + an empty response. When this flag is true, workers should allow polls to return gracefully + rather than terminating any open polls on shutdown. description: Namespace capability details. Should contain what features are enabled in a namespace. NamespaceInfo_Limits: type: object @@ -14034,6 +14054,12 @@ components: StopBatchOperationResponse: type: object properties: {} + StorageDriverInfo: + type: object + properties: + type: + type: string + description: The type of the driver, required. StructuredCalendarSpec: type: object properties: @@ -15507,6 +15533,11 @@ components: items: $ref: '#/components/schemas/PluginInfo' description: Plugins currently in use by this SDK. + drivers: + type: array + items: + $ref: '#/components/schemas/StorageDriverInfo' + description: Storage drivers in use by this SDK. description: |- Worker info message, contains information about the worker and its current state. All information is provided by the worker itself. @@ -15547,6 +15578,71 @@ components: properties: workerHeartbeat: $ref: '#/components/schemas/WorkerHeartbeat' + description: Detailed worker information. + WorkerListInfo: + type: object + properties: + workerInstanceKey: + type: string + description: |- + Worker identifier, should be unique for the namespace. + It is distinct from worker identity, which is not necessarily namespace-unique. + workerIdentity: + type: string + description: |- + Worker identity, set by the client, may not be unique. + Usually host_name+(user group name)+process_id, but can be overwritten by the user. + taskQueue: + type: string + description: Task queue this worker is polling for tasks. + deploymentVersion: + $ref: '#/components/schemas/WorkerDeploymentVersion' + sdkName: + type: string + sdkVersion: + type: string + status: + enum: + - WORKER_STATUS_UNSPECIFIED + - WORKER_STATUS_RUNNING + - WORKER_STATUS_SHUTTING_DOWN + - WORKER_STATUS_SHUTDOWN + type: string + description: Worker status. Defined by SDK. + format: enum + startTime: + type: string + description: |- + Worker start time. + It can be used to determine worker uptime. (current time - start time) + format: date-time + hostName: + type: string + description: Worker host identifier. + workerGroupingKey: + type: string + description: |- + Worker grouping identifier. A key to group workers that share the same client+namespace+process. + This will be used to build the worker command nexus task queue name: + "temporal-sys/worker-commands/{worker_grouping_key}" + processId: + type: string + description: |- + Worker process identifier. This id only needs to be unique + within one host (so using e.g. a unix pid would be appropriate). + plugins: + type: array + items: + $ref: '#/components/schemas/PluginInfo' + description: Plugins currently in use by this SDK. + drivers: + type: array + items: + $ref: '#/components/schemas/StorageDriverInfo' + description: Storage drivers in use by this SDK. + description: |- + Limited worker information returned in the list response. + When adding fields here, ensure that it is also added to WorkerInfo (as it carries the full worker information). WorkerPollerInfo: type: object properties: @@ -16440,6 +16536,20 @@ components: A boolean indicating whether the SDK has asked to eagerly execute the first workflow task for this workflow and eager execution was accepted by the server. Only populated by server with version >= 1.29.0. + declinedTargetVersionUpgrade: + allOf: + - $ref: '#/components/schemas/DeclinedTargetVersionUpgrade' + description: |- + During a previous run of this workflow, the server may have notified the SDK + that the Target Worker Deployment Version changed, but the SDK declined to + upgrade (e.g., by continuing-as-new with PINNED behavior). This field records + the target version that was declined. + + This is a wrapper message to distinguish "never declined" (nil wrapper) from + "declined an unversioned target" (non-nil wrapper with nil deployment_version). + + Used internally by the server during continue-as-new and retry. + Should not be read or interpreted by SDKs. description: Always the first event in workflow history WorkflowExecutionTerminatedEventAttributes: type: object diff --git a/temporal/api/history/v1/message.proto b/temporal/api/history/v1/message.proto index 2fb99f7e9..21fb13c5e 100644 --- a/temporal/api/history/v1/message.proto +++ b/temporal/api/history/v1/message.proto @@ -184,6 +184,24 @@ message WorkflowExecutionStartedEventAttributes { // eager execution was accepted by the server. // Only populated by server with version >= 1.29.0. bool eager_execution_accepted = 38; + + // During a previous run of this workflow, the server may have notified the SDK + // that the Target Worker Deployment Version changed, but the SDK declined to + // upgrade (e.g., by continuing-as-new with PINNED behavior). This field records + // the target version that was declined. + // + // This is a wrapper message to distinguish "never declined" (nil wrapper) from + // "declined an unversioned target" (non-nil wrapper with nil deployment_version). + // + // Used internally by the server during continue-as-new and retry. + // Should not be read or interpreted by SDKs. + DeclinedTargetVersionUpgrade declined_target_version_upgrade = 40; +} + +// Wrapper for a target deployment version that the SDK declined to upgrade to. +// See declined_target_version_upgrade on WorkflowExecutionStartedEventAttributes. +message DeclinedTargetVersionUpgrade { + temporal.api.deployment.v1.WorkerDeploymentVersion deployment_version = 1; } message WorkflowExecutionCompletedEventAttributes { diff --git a/temporal/api/namespace/v1/message.proto b/temporal/api/namespace/v1/message.proto index b6f5c4cda..9f52e3452 100644 --- a/temporal/api/namespace/v1/message.proto +++ b/temporal/api/namespace/v1/message.proto @@ -42,6 +42,12 @@ message NamespaceInfo { bool workflow_pause = 6; // True if the namespace supports standalone activities bool standalone_activities = 7; + // True if the namespace supports server-side completion of outstanding worker polls on shutdown. + // When enabled, the server will complete polls for workers that send WorkerInstanceKey in their + // poll requests and call ShutdownWorker with the same WorkerInstanceKey. The poll will return + // an empty response. When this flag is true, workers should allow polls to return gracefully + // rather than terminating any open polls on shutdown. + bool worker_poll_complete_on_shutdown = 8; } // Namespace configured limits diff --git a/temporal/api/nexusservices/workerservice/v1/request_response.proto b/temporal/api/nexusservices/workerservice/v1/request_response.proto new file mode 100644 index 000000000..ef14decbd --- /dev/null +++ b/temporal/api/nexusservices/workerservice/v1/request_response.proto @@ -0,0 +1,46 @@ +syntax = "proto3"; + +package temporal.api.nexusservices.workerservice.v1; + +option go_package = "go.temporal.io/api/nexusservices/workerservice/v1;workerservice"; +option java_package = "io.temporal.api.nexusservices.workerservice.v1"; +option java_multiple_files = true; +option java_outer_classname = "RequestResponseProto"; +option ruby_package = "Temporalio::Api::Nexusservices::Workerservice::V1"; +option csharp_namespace = "Temporalio.Api.Nexusservices.Workerservice.V1"; + +// (-- +// Internal Nexus service for server-to-worker communication. +// See service.yaml for the service definition. +// --) + +// Request payload for the "executeCommands" Nexus operation. +message WorkerCommandsRequest { + repeated WorkerCommand commands = 1; + + message WorkerCommand { + oneof type { + CancelActivity cancel_activity = 1; + } + } + + // Cancel an activity if it is still running. Otherwise, do nothing. + message CancelActivity { + bytes task_token = 1; + } +} + +// Response payload for the "executeCommands" Nexus operation. +message WorkerCommandsResponse { + repeated WorkerCommandResult results = 1; + + message WorkerCommandResult { + oneof type { + CancelActivity cancel_activity = 1; + } + } + + // Treat both successful cancellation and no-op (activity is no longer running) as success. + message CancelActivity { + } +} diff --git a/temporal/api/nexusservices/workerservice/v1/service.yaml b/temporal/api/nexusservices/workerservice/v1/service.yaml new file mode 100644 index 000000000..ad42b3bba --- /dev/null +++ b/temporal/api/nexusservices/workerservice/v1/service.yaml @@ -0,0 +1,32 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nexus-rpc/nexus-rpc-gen/main/schemas/nexus-rpc-gen.json +# +# Nexus service definition for server-to-worker communication. +# See request_response.proto for message definitions. +# +# Task queue format: /temporal-sys/worker-commands/{namespace}/{worker_grouping_key} + +nexusrpc: 1.0.0 + +services: + temporal.api.nexusservices.workerservice.v1.WorkerService: + description: > + Internal Nexus service for server-to-worker communication. + Used by the Temporal server to send commands to workers. + operations: + executeCommands: + description: Executes worker commands sent by the server. + input: + $goRef: "go.temporal.io/api/nexusservices/workerservice/v1.WorkerCommandsRequest" + $javaRef: "io.temporal.api.nexusservices.workerservice.v1.WorkerCommandsRequest" + $pythonRef: "temporalio.api.nexusservices.workerservice.v1.WorkerCommandsRequest" + $typescriptRef: "@temporalio/api/nexusservices/workerservice/v1.WorkerCommandsRequest" + $dotnetRef: "Temporalio.Api.Nexusservices.Workerservice.V1.WorkerCommandsRequest" + $rubyRef: "Temporalio::Api::Nexusservices::Workerservice::V1::WorkerCommandsRequest" + output: + $goRef: "go.temporal.io/api/nexusservices/workerservice/v1.WorkerCommandsResponse" + $javaRef: "io.temporal.api.nexusservices.workerservice.v1.WorkerCommandsResponse" + $pythonRef: "temporalio.api.nexusservices.workerservice.v1.WorkerCommandsResponse" + $typescriptRef: "@temporalio/api/nexusservices/workerservice/v1.WorkerCommandsResponse" + $dotnetRef: "Temporalio.Api.Nexusservices.Workerservice.V1.WorkerCommandsResponse" + $rubyRef: "Temporalio::Api::Nexusservices::Workerservice::V1::WorkerCommandsResponse" + diff --git a/temporal/api/worker/v1/message.proto b/temporal/api/worker/v1/message.proto index 3df3aaa33..b65faeb29 100644 --- a/temporal/api/worker/v1/message.proto +++ b/temporal/api/worker/v1/message.proto @@ -127,15 +127,69 @@ message WorkerHeartbeat { // Plugins currently in use by this SDK. repeated PluginInfo plugins = 23; + + // Storage drivers in use by this SDK. + repeated StorageDriverInfo drivers = 24; } +// Detailed worker information. message WorkerInfo { WorkerHeartbeat worker_heartbeat = 1; } +// Limited worker information returned in the list response. +// When adding fields here, ensure that it is also added to WorkerInfo (as it carries the full worker information). +message WorkerListInfo { + // Worker identifier, should be unique for the namespace. + // It is distinct from worker identity, which is not necessarily namespace-unique. + string worker_instance_key = 1; + + // Worker identity, set by the client, may not be unique. + // Usually host_name+(user group name)+process_id, but can be overwritten by the user. + string worker_identity = 2; + + // Task queue this worker is polling for tasks. + string task_queue = 3; + + temporal.api.deployment.v1.WorkerDeploymentVersion deployment_version = 4; + + string sdk_name = 5; + string sdk_version = 6; + + // Worker status. Defined by SDK. + temporal.api.enums.v1.WorkerStatus status = 7; + + // Worker start time. + // It can be used to determine worker uptime. (current time - start time) + google.protobuf.Timestamp start_time = 8; + + // Worker host identifier. + string host_name = 9; + + // Worker grouping identifier. A key to group workers that share the same client+namespace+process. + // This will be used to build the worker command nexus task queue name: + // "temporal-sys/worker-commands/{worker_grouping_key}" + string worker_grouping_key = 10; + + // Worker process identifier. This id only needs to be unique + // within one host (so using e.g. a unix pid would be appropriate). + string process_id = 11; + + // Plugins currently in use by this SDK. + repeated PluginInfo plugins = 12; + + // Storage drivers in use by this SDK. + repeated StorageDriverInfo drivers = 13; +} + message PluginInfo { // The name of the plugin, required. string name = 1; // The version of the plugin, may be empty. string version = 2; } + +message StorageDriverInfo { + // The type of the driver, required. + string type = 1; +} diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index 4bf3272c6..e95ac8ba4 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -262,6 +262,10 @@ message PollWorkflowTaskQueueRequest { // 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; + + // The task queue on which the server will send control tasks to this worker. + string worker_control_task_queue = 9; + // 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. @@ -381,6 +385,13 @@ message RespondWorkflowTaskCompletedRequest { // Worker deployment options that user has set in the worker. temporal.api.deployment.v1.WorkerDeploymentOptions deployment_options = 17; + // 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 = 18; + + // The task queue on which the server will send control tasks to this worker. + string worker_control_task_queue = 19; + // SDK capability details. message Capabilities { // True if the SDK can handle speculative workflow task with command events. If true, the @@ -444,6 +455,10 @@ message PollActivityTaskQueueRequest { // 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; + + // The task queue on which the server will send control tasks to this worker. + string worker_control_task_queue = 9; + 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. @@ -2560,8 +2575,8 @@ message ListWorkersRequest { int32 page_size = 2; bytes next_page_token = 3; - // `query` in ListWorkers is used to filter workers based on worker status info. - // The following worker status attributes are expected are supported as part of the query: + // `query` in ListWorkers is used to filter workers based on worker attributes. + // Supported attributes: //* WorkerInstanceKey //* WorkerIdentity //* HostName @@ -2571,14 +2586,17 @@ message ListWorkersRequest { //* SdkName //* SdkVersion //* StartTime - //* LastHeartbeatTime //* Status - // Currently metrics are not supported as a part of ListWorkers query. string query = 4; } message ListWorkersResponse { - repeated temporal.api.worker.v1.WorkerInfo workers_info = 1; + // Deprecated: Use workers instead. This field returns full WorkerInfo which + // includes expensive runtime metrics. We will stop populating this field in the future. + repeated temporal.api.worker.v1.WorkerInfo workers_info = 1 [deprecated = true]; + + // Limited worker information. + repeated temporal.api.worker.v1.WorkerListInfo workers = 3; // Next page token bytes next_page_token = 2;