From 2227a14f482ae48fc440a5e9829cf6797009d5b8 Mon Sep 17 00:00:00 2001 From: Shahab Tajik Date: Wed, 10 Apr 2024 22:39:10 +0200 Subject: [PATCH] Versioning 2 API (#393) Worker Versioning 2 API Co-authored-by: Carly de Frondeville --- buf.yaml | 3 + openapi/openapiv2.json | 477 ++++++++++++++++-- openapi/openapiv3.yaml | 353 ++++++++++++- temporal/api/command/v1/message.proto | 20 +- temporal/api/common/v1/message.proto | 5 +- temporal/api/enums/v1/task_queue.proto | 28 + temporal/api/history/v1/message.proto | 39 +- temporal/api/taskqueue/v1/message.proto | 116 +++++ temporal/api/workflow/v1/message.proto | 25 + .../workflowservice/v1/request_response.proto | 153 ++++++ temporal/api/workflowservice/v1/service.proto | 24 +- 11 files changed, 1161 insertions(+), 82 deletions(-) diff --git a/buf.yaml b/buf.yaml index 1d7fb070..54630f6d 100644 --- a/buf.yaml +++ b/buf.yaml @@ -15,6 +15,9 @@ breaking: - temporal/api/operatorservice/v1/request_response.proto - temporal/api/operatorservice/v1/service.proto - temporal/api/nexus/v1/message.proto + - temporal/api/command/v1/message.proto + - temporal/api/history/v1/message.proto + - temporal/api/common/v1/message.proto lint: use: - DEFAULT diff --git a/openapi/openapiv2.json b/openapi/openapiv2.json index 864f8676..c5a3512f 100644 --- a/openapi/openapiv2.json +++ b/openapi/openapiv2.json @@ -1071,7 +1071,7 @@ }, "/api/v1/namespaces/{namespace}/task-queues/{taskQueue.name}": { "get": { - "summary": "DescribeTaskQueue returns information about the target task queue.", + "summary": "DescribeTaskQueue returns the following information about the target task queue, broken down by Build ID:\n - List of pollers\n - Workflow Reachability status\n - Backlog info for Workflow and/or Activity tasks", "operationId": "DescribeTaskQueue", "responses": { "200": { @@ -1122,7 +1122,7 @@ }, { "name": "taskQueueType", - "description": "If unspecified (TASK_QUEUE_TYPE_UNSPECIFIED), then default value (TASK_QUEUE_TYPE_WORKFLOW) will be used.\n\n - TASK_QUEUE_TYPE_WORKFLOW: Workflow type of task queue.\n - TASK_QUEUE_TYPE_ACTIVITY: Activity type of task queue.\n - TASK_QUEUE_TYPE_NEXUS: Task queue type for dispatching Nexus requests.", + "description": "Deprecated. Use `ENHANCED` mode with `task_queue_types`. Ignored in `ENHANCED` mode.\nIf unspecified (TASK_QUEUE_TYPE_UNSPECIFIED), then default value (TASK_QUEUE_TYPE_WORKFLOW) will be used.\n\n - TASK_QUEUE_TYPE_WORKFLOW: Workflow type of task queue.\n - TASK_QUEUE_TYPE_ACTIVITY: Activity type of task queue.\n - TASK_QUEUE_TYPE_NEXUS: Task queue type for dispatching Nexus requests.", "in": "query", "required": false, "type": "string", @@ -1136,6 +1136,75 @@ }, { "name": "includeTaskQueueStatus", + "description": "Deprecated. Ignored in `ENHANCED` mode.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "apiMode", + "description": "All options except `task_queue_type` and `include_task_queue_status` are only available in the `ENHANCED` mode.\n\n - DESCRIBE_TASK_QUEUE_MODE_UNSPECIFIED: Unspecified means legacy behavior.\n - DESCRIBE_TASK_QUEUE_MODE_ENHANCED: Enhanced mode reports aggregated results for all partitions, supports Build IDs, and reports richer info.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "DESCRIBE_TASK_QUEUE_MODE_UNSPECIFIED", + "DESCRIBE_TASK_QUEUE_MODE_ENHANCED" + ], + "default": "DESCRIBE_TASK_QUEUE_MODE_UNSPECIFIED" + }, + { + "name": "versions.buildIds", + "description": "Include specific Build IDs.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "versions.unversioned", + "description": "Include the unversioned queue.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "versions.allActive", + "description": "Include all active versions. A version is considered active if it has had new\ntasks or polls recently.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "taskQueueTypes", + "description": "Task queue types to report info about. If not specified, all types are considered.\n\n - TASK_QUEUE_TYPE_WORKFLOW: Workflow type of task queue.\n - TASK_QUEUE_TYPE_ACTIVITY: Activity type of task queue.\n - TASK_QUEUE_TYPE_NEXUS: Task queue type for dispatching Nexus requests.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string", + "enum": [ + "TASK_QUEUE_TYPE_UNSPECIFIED", + "TASK_QUEUE_TYPE_WORKFLOW", + "TASK_QUEUE_TYPE_ACTIVITY", + "TASK_QUEUE_TYPE_NEXUS" + ] + }, + "collectionFormat": "multi" + }, + { + "name": "reportPollers", + "description": "Report backlog info for the requested task queue types and versions\nbool report_backlog_info = 8;\nReport list of pollers for requested task queue types and versions", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "reportTaskReachability", + "description": "Report task reachability for the requested versions and all task types (task reachability is not reported\nper task type).", "in": "query", "required": false, "type": "boolean" @@ -1148,7 +1217,7 @@ }, "/api/v1/namespaces/{namespace}/task-queues/{taskQueue}/worker-build-id-compatibility": { "get": { - "summary": "Fetches the worker build id versioning sets for a task queue.", + "summary": "Deprecated. Use `GetWorkerVersioningRules`.\nFetches the worker build id versioning sets for a task queue.", "operationId": "GetWorkerBuildIdCompatibility", "responses": { "200": { @@ -1192,6 +1261,43 @@ ] } }, + "/api/v1/namespaces/{namespace}/task-queues/{taskQueue}/worker-versioning-rules": { + "get": { + "summary": "Fetches the Build ID assignment and redirect rules for a Task Queue.\nWARNING: Worker Versioning is not yet stable and the API and behavior may change incompatibly.", + "operationId": "GetWorkerVersioningRules", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetWorkerVersioningRulesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "taskQueue", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "WorkflowService" + ] + } + }, "/api/v1/namespaces/{namespace}/update": { "post": { "summary": "UpdateNamespace is used to update the information and configuration of a registered\nnamespace.", @@ -1233,8 +1339,8 @@ }, "/api/v1/namespaces/{namespace}/worker-task-reachability": { "get": { - "summary": "Fetches task reachability to determine whether a worker may be retired.\nThe request may specify task queues to query for or let the server fetch all task queues mapped to the given\nbuild IDs.", - "description": "When requesting a large number of task queues or all task queues associated with the given build ids in a\nnamespace, all task queues will be listed in the response but some of them may not contain reachability\ninformation due to a server enforced limit. When reaching the limit, task queues that reachability information\ncould not be retrieved for will be marked with a single TASK_REACHABILITY_UNSPECIFIED entry. The caller may issue\nanother call to get the reachability for those task queues.\n\nOpen source users can adjust this limit by setting the server's dynamic config value for\n`limit.reachabilityTaskQueueScan` with the caveat that this call can strain the visibility store.", + "summary": "Deprecated. Use `DescribeTaskQueue`.", + "description": "Fetches task reachability to determine whether a worker may be retired.\nThe request may specify task queues to query for or let the server fetch all task queues mapped to the given\nbuild IDs.\n\nWhen requesting a large number of task queues or all task queues associated with the given build ids in a\nnamespace, all task queues will be listed in the response but some of them may not contain reachability\ninformation due to a server enforced limit. When reaching the limit, task queues that reachability information\ncould not be retrieved for will be marked with a single TASK_REACHABILITY_UNSPECIFIED entry. The caller may issue\nanother call to get the reachability for those task queues.\n\nOpen source users can adjust this limit by setting the server's dynamic config value for\n`limit.reachabilityTaskQueueScan` with the caveat that this call can strain the visibility store.", "operationId": "GetWorkerTaskReachability", "responses": { "200": { @@ -2075,6 +2181,89 @@ } } }, + "UpdateWorkerVersioningRulesRequestAddCompatibleBuildIdRedirectRule": { + "type": "object", + "properties": { + "rule": { + "$ref": "#/definitions/v1CompatibleBuildIdRedirectRule" + } + }, + "description": "Adds the rule to the list of redirect rules for this Task Queue. There\ncan be at most one redirect rule for each distinct Source Build ID." + }, + "UpdateWorkerVersioningRulesRequestCommitBuildId": { + "type": "object", + "properties": { + "targetBuildId": { + "type": "string" + }, + "force": { + "type": "boolean", + "description": "To prevent committing invalid Build IDs, we reject the request if no\npollers has been seen recently for this Build ID. Use the `force`\noption to disable this validation." + } + }, + "description": "This command is intended to be used to complete the rollout of a Build\nID and cleanup unnecessary rules possibly created during a gradual\nrollout. Specifically, this command will make the following changes\natomically:\n 1. Adds an assignment rule (with full ramp) for the target Build ID at\n the end of the list.\n 2. Removes all previously added assignment rules to the given target\n Build ID (if any).\n 3. Removes any fully-ramped assignment rule for other Build IDs." + }, + "UpdateWorkerVersioningRulesRequestDeleteBuildIdAssignmentRule": { + "type": "object", + "properties": { + "ruleIndex": { + "type": "integer", + "format": "int32" + }, + "force": { + "type": "boolean", + "title": "By default presence of one unconditional rule is enforced, otherwise\nthe delete operation will be rejected. Set `force` to true to\nbypass this validation. An unconditional assignment rule:\n - Has no hint filter\n - Has no ramp" + } + } + }, + "UpdateWorkerVersioningRulesRequestDeleteCompatibleBuildIdRedirectRule": { + "type": "object", + "properties": { + "sourceBuildId": { + "type": "string" + } + } + }, + "UpdateWorkerVersioningRulesRequestInsertBuildIdAssignmentRule": { + "type": "object", + "properties": { + "ruleIndex": { + "type": "integer", + "format": "int32", + "description": "Use this option to insert the rule in a particular index. By\ndefault, the new rule is inserted at the beginning of the list\n(index 0). If the given index is too larger the rule will be\ninserted at the end of the list." + }, + "rule": { + "$ref": "#/definitions/v1BuildIdAssignmentRule" + } + }, + "description": "Inserts the rule to the list of assignment rules for this Task Queue.\nThe rules are evaluated in order, starting from index 0. The first\napplicable rule will be applied and the rest will be ignored." + }, + "UpdateWorkerVersioningRulesRequestReplaceBuildIdAssignmentRule": { + "type": "object", + "properties": { + "ruleIndex": { + "type": "integer", + "format": "int32" + }, + "rule": { + "$ref": "#/definitions/v1BuildIdAssignmentRule" + }, + "force": { + "type": "boolean", + "title": "By default presence of one unconditional rule is enforced, otherwise\nthe replace operation will be rejected. Set `force` to true to\nbypass this validation. An unconditional assignment rule:\n - Has no hint filter\n - Has no ramp" + } + }, + "description": "Replaces the assignment rule at a given index." + }, + "UpdateWorkerVersioningRulesRequestReplaceCompatibleBuildIdRedirectRule": { + "type": "object", + "properties": { + "rule": { + "$ref": "#/definitions/v1CompatibleBuildIdRedirectRule" + } + }, + "description": "Replaces the routing rule with the given source Build ID." + }, "WorkflowServiceCreateScheduleBody": { "type": "object", "properties": { @@ -3007,7 +3196,7 @@ }, "workerVersion": { "$ref": "#/definitions/v1WorkerVersionStamp", - "description": "Version info of the worker who processed this workflow task." + "title": "Version info of the worker who processed this workflow task.\nDeprecated. Use the info inside the corresponding ActivityTaskStartedEvent" } } }, @@ -3034,7 +3223,7 @@ }, "workerVersion": { "$ref": "#/definitions/v1WorkerVersionStamp", - "description": "Version info of the worker who processed this workflow task." + "title": "Version info of the worker who processed this workflow task.\nDeprecated. Use the info inside the corresponding ActivityTaskStartedEvent" } } }, @@ -3064,7 +3253,7 @@ }, "workerVersion": { "$ref": "#/definitions/v1WorkerVersionStamp", - "description": "Version info of the worker who processed this workflow task." + "title": "Version info of the worker who processed this workflow task.\nDeprecated. Use the info inside the corresponding ActivityTaskStartedEvent" } } }, @@ -3112,9 +3301,9 @@ "$ref": "#/definitions/v1RetryPolicy", "description": "Activities are assigned a default retry policy controlled by the service's dynamic\nconfiguration. Retries will happen up to `schedule_to_close_timeout`. To disable retries set\nretry_policy.maximum_attempts to 1." }, - "useCompatibleVersion": { + "useWorkflowBuildId": { "type": "boolean", - "description": "If this is set, the workflow executing this command wishes to start the activity using\na version compatible with the version that this workflow most recently ran on, if such\nbehavior is possible." + "description": "If this is set, the activity would be assigned to the Build ID of the workflow. Otherwise,\nAssignment rules of the activity's Task Queue will be used to determine the Build ID." } } }, @@ -3142,6 +3331,15 @@ "lastFailure": { "$ref": "#/definitions/apifailurev1Failure", "description": "Will be set to the most recent failure details, if this task has previously failed and then\nbeen retried." + }, + "workerVersion": { + "$ref": "#/definitions/v1WorkerVersionStamp", + "description": "Version info of the worker to whom this task was dispatched." + }, + "buildIdRedirectCounter": { + "type": "string", + "format": "int64", + "description": "Used by server internally to properly reapply build ID redirects to an execution\nwhen rebuilding it from events." } } }, @@ -3388,6 +3586,19 @@ ], "default": "BATCH_OPERATION_TYPE_UNSPECIFIED" }, + "v1BuildIdAssignmentRule": { + "type": "object", + "properties": { + "targetBuildId": { + "type": "string" + }, + "percentageRamp": { + "$ref": "#/definitions/v1RampByPercentage", + "description": "This ramp is useful for gradual Blue/Green deployments (and similar)\nwhere you want to send a certain portion of the traffic to the target\nBuild ID." + } + }, + "description": "These rules assign a Build ID to Unassigned Workflow Executions and\nActivities.\n\nSpecifically, assignment rules are applied to the following Executions or\nActivities when they are scheduled in a Task Queue:\n - Generally, any new Workflow Execution, except:\n - When A Child Workflow or a Continue-As-New Execution inherits the\n Build ID from its parent/previous execution by setting the\n `inherit_build_id` flag.\n - Workflow Executions started Eagerly are assigned to the Build ID of\n the Starter.\n - An Activity that is scheduled on a Task Queue different from the one\n their Workflow runs on, unless the `use_workflow_build_id` flag is set.\n\nIn absence of (applicable) redirect rules (`CompatibleBuildIdRedirectRule`s)\nthe task will be dispatched to Workers of the Build ID determined by the\nassignment rules. Otherwise, the final Build ID will be determined by the\nredirect rules.\n\nWhen using Worker Versioning, in the steady state, for a given Task Queue,\nthere should typically be exactly one assignment rule to send all Unassigned\ntasks to the latest Build ID. Existence of at least one such \"unconditional\"\nrule at all times is enforce by the system, unless the `force` flag is used\nby the user when replacing/deleting these rules (for exceptional cases).\n\nDuring a deployment, one or more additional rules can be added to assign a\nsubset of the tasks to a new Build ID based on a \"ramp percentage\".\n\nWhen there are multiple assignment rules for a Task Queue, the rules are\nevaluated in order, starting from index 0. The first applicable rule will be\napplied and the rest will be ignored.\n\nIn the event that no assignment rule is applicable on a task (or the Task\nQueue is simply not versioned), the tasks will be sent to unversioned\nworkers, if available. Otherwise, they remain Unassigned, and will be\nretried for assignment, or dispatch to unversioned workers, at a later time\ndepending on the availability of workers." + }, "v1BuildIdReachability": { "type": "object", "properties": { @@ -3406,6 +3617,17 @@ }, "description": "Reachability of tasks for a worker by build id, in one or more task queues." }, + "v1BuildIdTaskReachability": { + "type": "string", + "enum": [ + "BUILD_ID_TASK_REACHABILITY_UNSPECIFIED", + "BUILD_ID_TASK_REACHABILITY_REACHABLE", + "BUILD_ID_TASK_REACHABILITY_CLOSED_WORKFLOWS_ONLY", + "BUILD_ID_TASK_REACHABILITY_UNREACHABLE" + ], + "default": "BUILD_ID_TASK_REACHABILITY_UNSPECIFIED", + "description": "Specifies which category of tasks may reach a versioned worker of a certain Build ID.\nNote: future activities who inherit their workflow's Build ID but not its Task Queue will not be\naccounted for reachability as server cannot not know if they'll happen as they do not use\nassignment rules of their Task Queue. Same goes for Child Workflows or Continue-As-New Workflows\nwho inherit the parent/previous workflow's Build ID but not its Task Queue. In those cases, make\nsure to query reachability for the parent/previous workflow's Task Queue as well.\n\n - BUILD_ID_TASK_REACHABILITY_UNSPECIFIED: Task reachability is not reported\n - BUILD_ID_TASK_REACHABILITY_REACHABLE: Build ID may be used by new workflows or activities (base on versioning rules), or there are\nopen workflows or backlogged activities assigned to it.\n - BUILD_ID_TASK_REACHABILITY_CLOSED_WORKFLOWS_ONLY: Build ID does not have open workflows and is not reachable by new workflows,\nbut MAY have closed workflows within the namespace retention period.\nNot applicable to activity-only task queues.\n - BUILD_ID_TASK_REACHABILITY_UNREACHABLE: Build ID is not used for new executions, nor it has been used by any existing execution\nwithin the retention period." + }, "v1CalendarSpec": { "type": "object", "properties": { @@ -3885,6 +4107,18 @@ "default": "COMMAND_TYPE_UNSPECIFIED", "description": "Whenever this list of command types is changed do change the function shouldBufferEvent in mutableStateBuilder.go to make sure to do the correct event ordering." }, + "v1CompatibleBuildIdRedirectRule": { + "type": "object", + "properties": { + "sourceBuildId": { + "type": "string" + }, + "targetBuildId": { + "type": "string" + } + }, + "description": "These rules apply to tasks assigned to a particular Build ID\n(`source_build_id`) to redirect them to another *compatible* Build ID\n(`target_build_id`).\n\nIt is user's responsibility to ensure that the target Build ID is compatible\nwith the source Build ID (e.g. by using the Patching API).\n\nMost deployments are not expected to need these rules, however following\nsituations can greatly benefit from redirects:\n - Need to move long-running Workflow Executions from an old Build ID to a\n newer one.\n - Need to hotfix some broken or stuck Workflow Executions.\n\nIn steady state, redirect rules are beneficial when dealing with old\nExecutions ran on now-decommissioned Build IDs:\n - To redirecting the Workflow Queries to the current (compatible) Build ID.\n - To be able to Reset an old Execution so it can run on the current\n (compatible) Build ID.\n\nRedirect rules can be chained, but only the last rule in the chain can have\na ramp." + }, "v1CompatibleVersionSet": { "type": "object", "properties": { @@ -3969,9 +4203,9 @@ "searchAttributes": { "$ref": "#/definitions/v1SearchAttributes" }, - "useCompatibleVersion": { + "inheritBuildId": { "type": "boolean", - "description": "If this is set, the workflow executing this command wishes to continue as new using a version\ncompatible with the version that this workflow most recently ran on." + "description": "If this is set, the new execution inherits the Build ID of the current execution. Otherwise,\nthe assignment rules will be used to independently assign a Build ID to the new execution." } } }, @@ -4161,6 +4395,15 @@ } } }, + "v1DescribeTaskQueueMode": { + "type": "string", + "enum": [ + "DESCRIBE_TASK_QUEUE_MODE_UNSPECIFIED", + "DESCRIBE_TASK_QUEUE_MODE_ENHANCED" + ], + "default": "DESCRIBE_TASK_QUEUE_MODE_UNSPECIFIED", + "description": " - DESCRIBE_TASK_QUEUE_MODE_UNSPECIFIED: Unspecified means legacy behavior.\n - DESCRIBE_TASK_QUEUE_MODE_ENHANCED: Enhanced mode reports aggregated results for all partitions, supports Build IDs, and reports richer info." + }, "v1DescribeTaskQueueResponse": { "type": "object", "properties": { @@ -4169,10 +4412,19 @@ "items": { "type": "object", "$ref": "#/definitions/v1PollerInfo" - } + }, + "description": "Deprecated. Use `versions_info.types_info.pollers` with `ENHANCED` mode instead.\nNot set in `ENHANCED` mode." }, "taskQueueStatus": { - "$ref": "#/definitions/v1TaskQueueStatus" + "$ref": "#/definitions/v1TaskQueueStatus", + "description": "Deprecated. Not set in `ENHANCED` mode." + }, + "versionsInfo": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/v1TaskQueueVersionInfo" + }, + "description": "This map contains Task Queue information for each Build ID. Empty string as key value means unversioned.\nOnly set in `ENHANCED` mode." } } }, @@ -4488,6 +4740,31 @@ }, "description": "Task reachability, broken down by build id and then task queue.\nWhen requesting a large number of task queues or all task queues associated with the given build ids in a\nnamespace, all task queues will be listed in the response but some of them may not contain reachability\ninformation due to a server enforced limit. When reaching the limit, task queues that reachability information\ncould not be retrieved for will be marked with a single TASK_REACHABILITY_UNSPECIFIED entry. The caller may issue\nanother call to get the reachability for those task queues.\n\nOpen source users can adjust this limit by setting the server's dynamic config value for\n`limit.reachabilityTaskQueueScan` with the caveat that this call can strain the visibility store." } + }, + "description": "Deprecated. Use `DescribeTaskQueue`." + }, + "v1GetWorkerVersioningRulesResponse": { + "type": "object", + "properties": { + "assignmentRules": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1TimestampedBuildIdAssignmentRule" + } + }, + "compatibleRedirectRules": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1TimestampedCompatibleBuildIdRedirectRule" + } + }, + "conflictToken": { + "type": "string", + "format": "byte", + "description": "This value can be passed back to UpdateWorkerVersioningRulesRequest to\nensure that the rules were not modified between this List and the Update,\nwhich could lead to lost updates and other confusion." + } } }, "v1GetWorkflowExecutionHistoryResponse": { @@ -5467,6 +5744,19 @@ }, "lastWorkerIdentity": { "type": "string" + }, + "useWorkflowBuildId": { + "type": "object", + "properties": {}, + "description": "When present, it means this activity is assigned to the build ID of its workflow." + }, + "lastIndependentlyAssignedBuildId": { + "type": "string", + "description": "This means the activity is independently versioned and not bound to the build ID of its workflow.\nThe activity will use the build id in this field instead.\nIf the task fails and is scheduled again, the assigned build ID may change according to the latest versioning\nrules." + }, + "lastWorkerVersionStamp": { + "$ref": "#/definitions/v1WorkerVersionStamp", + "title": "The version stamp of the worker to whom this activity was most recently dispatched" } } }, @@ -5790,6 +6080,16 @@ } } }, + "v1RampByPercentage": { + "type": "object", + "properties": { + "rampPercentage": { + "type": "number", + "format": "float", + "description": "Acceptable range is [0,100)." + } + } + }, "v1Range": { "type": "object", "properties": { @@ -6390,9 +6690,9 @@ "type": "boolean", "description": "Request to start the activity directly bypassing matching service and worker polling\nThe slot for executing the activity should be reserved when setting this field to true." }, - "useCompatibleVersion": { + "useWorkflowBuildId": { "type": "boolean", - "description": "If this is set, the workflow executing this command wishes to start the activity using\na version compatible with the version that this workflow most recently ran on, if such\nbehavior is possible." + "description": "If this is set, the activity would be assigned to the Build ID of the workflow. Otherwise,\nAssignment rules of the activity's Task Queue will be used to determine the Build ID." } } }, @@ -6888,9 +7188,9 @@ "searchAttributes": { "$ref": "#/definitions/v1SearchAttributes" }, - "useCompatibleVersion": { + "inheritBuildId": { "type": "boolean", - "description": "If this is set, the workflow executing this command wishes to start the child workflow using\na version compatible with the version that this workflow most recently ran on, if such\nbehavior is possible." + "description": "If this is set, the child workflow inherits the Build ID of the parent. Otherwise, the assignment\nrules of the child's Task Queue will be used to independently assign a Build ID to it." } } }, @@ -7005,9 +7305,9 @@ "searchAttributes": { "$ref": "#/definitions/v1SearchAttributes" }, - "useCompatibleVersion": { + "inheritBuildId": { "type": "boolean", - "description": "If this is set, the workflow executing this command wishes to start the child workflow using\na version compatible with the version that this workflow most recently ran on, if such\nbehavior is possible." + "description": "If this is set, the child workflow inherits the Build ID of the parent. Otherwise, the assignment\nrules of the child's Task Queue will be used to independently assign a Build ID to it." } } }, @@ -7281,7 +7581,8 @@ "taskIdBlock": { "$ref": "#/definitions/v1TaskIdBlock" } - } + }, + "description": "Deprecated. Use `InternalTaskQueueStatus`. This is kept until `DescribeTaskQueue` supports legacy behavior." }, "v1TaskQueueType": { "type": "string", @@ -7294,6 +7595,55 @@ "default": "TASK_QUEUE_TYPE_UNSPECIFIED", "description": " - TASK_QUEUE_TYPE_WORKFLOW: Workflow type of task queue.\n - TASK_QUEUE_TYPE_ACTIVITY: Activity type of task queue.\n - TASK_QUEUE_TYPE_NEXUS: Task queue type for dispatching Nexus requests." }, + "v1TaskQueueTypeInfo": { + "type": "object", + "properties": { + "pollers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1PollerInfo" + }, + "description": "Unversioned workers (with `useVersioning=false`) are reported in unversioned result even if they set a Build ID." + } + } + }, + "v1TaskQueueVersionInfo": { + "type": "object", + "properties": { + "typesInfo": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/v1TaskQueueTypeInfo" + }, + "description": "Task Queue info per Task Type. Key is the numerical value of the temporal.api.enums.v1.TaskQueueType enum." + }, + "taskReachability": { + "$ref": "#/definitions/v1BuildIdTaskReachability" + } + } + }, + "v1TaskQueueVersionSelection": { + "type": "object", + "properties": { + "buildIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Include specific Build IDs." + }, + "unversioned": { + "type": "boolean", + "description": "Include the unversioned queue." + }, + "allActive": { + "type": "boolean", + "description": "Include all active versions. A version is considered active if it has had new\ntasks or polls recently." + } + }, + "description": "Used for specifying versions the caller is interested in." + }, "v1TaskReachability": { "type": "string", "enum": [ @@ -7304,7 +7654,7 @@ "TASK_REACHABILITY_CLOSED_WORKFLOWS" ], "default": "TASK_REACHABILITY_UNSPECIFIED", - "description": "Specifies which category of tasks may reach a worker on a versioned task queue.\nUsed both in a reachability query and its response.\n\n - TASK_REACHABILITY_NEW_WORKFLOWS: There's a possiblity for a worker to receive new workflow tasks. Workers should *not* be retired.\n - TASK_REACHABILITY_EXISTING_WORKFLOWS: There's a possiblity for a worker to receive existing workflow and activity tasks from existing workflows. Workers\nshould *not* be retired.\nThis enum value does not distinguish between open and closed workflows.\n - TASK_REACHABILITY_OPEN_WORKFLOWS: There's a possiblity for a worker to receive existing workflow and activity tasks from open workflows. Workers\nshould *not* be retired.\n - TASK_REACHABILITY_CLOSED_WORKFLOWS: There's a possiblity for a worker to receive existing workflow tasks from closed workflows. Workers may be\nretired dependending on application requirements. For example, if there's no need to query closed workflows." + "description": "Specifies which category of tasks may reach a worker on a versioned task queue.\nUsed both in a reachability query and its response.\nDeprecated.\n\n - TASK_REACHABILITY_NEW_WORKFLOWS: There's a possiblity for a worker to receive new workflow tasks. Workers should *not* be retired.\n - TASK_REACHABILITY_EXISTING_WORKFLOWS: There's a possiblity for a worker to receive existing workflow and activity tasks from existing workflows. Workers\nshould *not* be retired.\nThis enum value does not distinguish between open and closed workflows.\n - TASK_REACHABILITY_OPEN_WORKFLOWS: There's a possiblity for a worker to receive existing workflow and activity tasks from open workflows. Workers\nshould *not* be retired.\n - TASK_REACHABILITY_CLOSED_WORKFLOWS: There's a possiblity for a worker to receive existing workflow tasks from closed workflows. Workers may be\nretired dependending on application requirements. For example, if there's no need to query closed workflows." }, "v1TerminateWorkflowExecutionResponse": { "type": "object" @@ -7389,6 +7739,30 @@ } } }, + "v1TimestampedBuildIdAssignmentRule": { + "type": "object", + "properties": { + "rule": { + "$ref": "#/definitions/v1BuildIdAssignmentRule" + }, + "createTime": { + "type": "string", + "format": "date-time" + } + } + }, + "v1TimestampedCompatibleBuildIdRedirectRule": { + "type": "object", + "properties": { + "rule": { + "$ref": "#/definitions/v1CompatibleBuildIdRedirectRule" + }, + "createTime": { + "type": "string", + "format": "date-time" + } + } + }, "v1TriggerImmediatelyRequest": { "type": "object", "properties": { @@ -7498,6 +7872,30 @@ "v1UpdateWorkerBuildIdCompatibilityResponse": { "type": "object" }, + "v1UpdateWorkerVersioningRulesResponse": { + "type": "object", + "properties": { + "assignmentRules": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1TimestampedBuildIdAssignmentRule" + } + }, + "compatibleRedirectRules": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1TimestampedCompatibleBuildIdRedirectRule" + } + }, + "conflictToken": { + "type": "string", + "format": "byte", + "description": "This value can be passed back to UpdateWorkerVersioningRulesRequest to\nensure that the rules were not modified between the two updates, which\ncould lead to lost updates and other confusion." + } + } + }, "v1UpdateWorkflowExecutionLifecycleStage": { "type": "string", "enum": [ @@ -7604,10 +8002,6 @@ "type": "string", "description": "An opaque whole-worker identifier. Replaces the deprecated `binary_checksum` field when this\nmessage is included in requests which previously used that." }, - "bundleId": { - "type": "string", - "description": "Set if the worker used a dynamically loadable bundle to process\nthe task. The bundle could be a WASM blob, JS bundle, etc." - }, "useVersioning": { "type": "boolean", "description": "If set, the worker is opting in to worker versioning. Otherwise, this is used only as a\nmarker for workflow reset points and the BuildIDs search attribute." @@ -7749,9 +8143,9 @@ "searchAttributes": { "$ref": "#/definitions/v1SearchAttributes" }, - "useCompatibleVersion": { + "inheritBuildId": { "type": "boolean", - "description": "If this is set, the workflow executing this command wishes to continue as new using a version\ncompatible with the version that this workflow most recently ran on." + "description": "If this is set, the new execution inherits the Build ID of the current execution. Otherwise,\nthe assignment rules will be used to independently assign a Build ID to the new execution." } } }, @@ -7852,6 +8246,14 @@ "rootExecution": { "$ref": "#/definitions/v1WorkflowExecution", "description": "Contains information about the root workflow execution.\nThe root workflow execution is defined as follows:\n1. A workflow without parent workflow is its own root workflow.\n2. A workflow that has a parent workflow has the same root workflow as its parent workflow.\nNote: workflows continued as new or reseted may or may not have parents, check examples below.\n\nExamples:\n Scenario 1: Workflow W1 starts child workflow W2, and W2 starts child workflow W3.\n - The root workflow of all three workflows is W1.\n Scenario 2: Workflow W1 starts child workflow W2, and W2 continued as new W3.\n - The root workflow of all three workflows is W1.\n Scenario 3: Workflow W1 continued as new W2.\n - The root workflow of W1 is W1 and the root workflow of W2 is W2.\n Scenario 4: Workflow W1 starts child workflow W2, and W2 is reseted, creating W3\n - The root workflow of all three workflows is W1.\n Scenario 5: Workflow W1 is reseted, creating W2.\n - The root workflow of W1 is W1 and the root workflow of W2 is W2." + }, + "assignedBuildId": { + "type": "string", + "description": "The currently assigned build ID for this execution. Presence of this value means worker versioning is used\nfor this execution. Assigned build ID is selected based on Worker Versioning Assignment Rules\nwhen the first workflow task of the execution is scheduled. If the first workflow task fails and is scheduled\nagain, the assigned build ID may change according to the latest versioning rules.\nAssigned build ID can also change in the middle of a execution if Compatible Redirect Rules are applied to\nthis execution." + }, + "inheritedBuildId": { + "type": "string", + "description": "Build ID inherited from a previous/parent execution. If present, assigned_build_id will be set to this, instead\nof using the assignment rules." } } }, @@ -7994,7 +8396,7 @@ }, "sourceVersionStamp": { "$ref": "#/definitions/v1WorkerVersionStamp", - "description": "If this workflow intends to use anything other than the current overall default version for\nthe queue, then we include it here." + "title": "If this workflow intends to use anything other than the current overall default version for\nthe queue, then we include it here.\nDeprecated. use `inherited_build_id` instead" }, "completionCallbacks": { "type": "array", @@ -8007,6 +8409,10 @@ "rootWorkflowExecution": { "$ref": "#/definitions/v1WorkflowExecution", "description": "Contains information about the root workflow execution.\nThe root workflow execution is defined as follows:\n1. A workflow without parent workflow is its own root workflow.\n2. A workflow that has a parent workflow has the same root workflow as its parent workflow.\nNote: workflows continued as new or reseted may or may not have parents, check examples below.\n\nExamples:\n Scenario 1: Workflow W1 starts child workflow W2, and W2 starts child workflow W3.\n - The root workflow of all three workflows is W1.\n Scenario 2: Workflow W1 starts child workflow W2, and W2 continued as new W3.\n - The root workflow of all three workflows is W1.\n Scenario 3: Workflow W1 continued as new W2.\n - The root workflow of W1 is W1 and the root workflow of W2 is W2.\n Scenario 4: Workflow W1 starts child workflow W2, and W2 is reseted, creating W3\n - The root workflow of all three workflows is W1.\n Scenario 5: Workflow W1 is reseted, creating W2.\n - The root workflow of W1 is W1 and the root workflow of W2 is W2." + }, + "inheritedBuildId": { + "type": "string", + "description": "When present, this execution is assigned to the build ID of its parent or previous execution." } }, "title": "Always the first event in workflow history" @@ -8254,7 +8660,7 @@ }, "workerVersion": { "$ref": "#/definitions/v1WorkerVersionStamp", - "description": "Version info of the worker who processed this workflow task. If present, the `build_id` field\nwithin is also used as `binary_checksum`, which may be omitted in that case (it may also be\npopulated to preserve compatibility)." + "title": "Version info of the worker who processed this workflow task. If present, the `build_id` field\nwithin is also used as `binary_checksum`, which may be omitted in that case (it may also be\npopulated to preserve compatibility).\nDeprecated. Use the info inside the corresponding WorkflowTaskStartedEvent" }, "sdkMetadata": { "$ref": "#/definitions/v1WorkflowTaskCompletedMetadata", @@ -8378,7 +8784,7 @@ }, "workerVersion": { "$ref": "#/definitions/v1WorkerVersionStamp", - "description": "Version info of the worker who processed this workflow task. If present, the `build_id` field\nwithin is also used as `binary_checksum`, which may be omitted in that case (it may also be\npopulated to preserve compatibility)." + "title": "Version info of the worker who processed this workflow task. If present, the `build_id` field\nwithin is also used as `binary_checksum`, which may be omitted in that case (it may also be\npopulated to preserve compatibility).\nDeprecated. Use the info inside the corresponding WorkflowTaskStartedEvent" } } }, @@ -8424,6 +8830,15 @@ "type": "string", "format": "int64", "description": "Total history size in bytes, which the workflow might use to decide when to\ncontinue-as-new regardless of the suggestion. Note that history event count is\njust the event id of this event, so we don't include it explicitly here." + }, + "workerVersion": { + "$ref": "#/definitions/v1WorkerVersionStamp", + "description": "Version info of the worker to whom this task was dispatched." + }, + "buildIdRedirectCounter": { + "type": "string", + "format": "int64", + "description": "Used by server internally to properly reapply build ID redirects to an execution\nwhen rebuilding it from events." } } }, diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index 01b7a933..52612acf 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -896,7 +896,9 @@ paths: get: tags: - WorkflowService - description: Fetches the worker build id versioning sets for a task queue. + description: |- + Deprecated. Use `GetWorkerVersioningRules`. + Fetches the worker build id versioning sets for a task queue. operationId: GetWorkerBuildIdCompatibility parameters: - name: namespace @@ -931,11 +933,47 @@ paths: application/json: schema: $ref: '#/components/schemas/Status' + /api/v1/namespaces/{namespace}/task-queues/{taskQueue}/worker-versioning-rules: + get: + tags: + - WorkflowService + description: |- + Fetches the Build ID assignment and redirect rules for a Task Queue. + WARNING: Worker Versioning is not yet stable and the API and behavior may change incompatibly. + operationId: GetWorkerVersioningRules + parameters: + - name: namespace + in: path + required: true + schema: + type: string + - name: taskQueue + in: path + required: true + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/GetWorkerVersioningRulesResponse' + default: + description: Default error response + content: + application/json: + schema: + $ref: '#/components/schemas/Status' /api/v1/namespaces/{namespace}/task-queues/{task_queue.name}: get: tags: - WorkflowService - description: DescribeTaskQueue returns information about the target task queue. + description: |- + DescribeTaskQueue returns the following information about the target task queue, broken down by Build ID: + - List of pollers + - Workflow Reachability status + - Backlog info for Workflow and/or Activity tasks operationId: DescribeTaskQueue parameters: - name: namespace @@ -971,7 +1009,9 @@ paths: type: string - name: taskQueueType in: query - description: If unspecified (TASK_QUEUE_TYPE_UNSPECIFIED), then default value (TASK_QUEUE_TYPE_WORKFLOW) will be used. + description: |- + Deprecated. Use `ENHANCED` mode with `task_queue_types`. Ignored in `ENHANCED` mode. + If unspecified (TASK_QUEUE_TYPE_UNSPECIFIED), then default value (TASK_QUEUE_TYPE_WORKFLOW) will be used. schema: enum: - TASK_QUEUE_TYPE_UNSPECIFIED @@ -982,6 +1022,63 @@ paths: format: enum - name: includeTaskQueueStatus in: query + description: Deprecated. Ignored in `ENHANCED` mode. + schema: + type: boolean + - name: apiMode + in: query + description: All options except `task_queue_type` and `include_task_queue_status` are only available in the `ENHANCED` mode. + schema: + enum: + - DESCRIBE_TASK_QUEUE_MODE_UNSPECIFIED + - DESCRIBE_TASK_QUEUE_MODE_ENHANCED + type: string + format: enum + - name: versions.buildIds + in: query + description: Include specific Build IDs. + schema: + type: array + items: + type: string + - name: versions.unversioned + in: query + description: Include the unversioned queue. + schema: + type: boolean + - name: versions.allActive + in: query + description: |- + Include all active versions. A version is considered active if it has had new + tasks or polls recently. + schema: + type: boolean + - name: taskQueueTypes + in: query + description: Task queue types to report info about. If not specified, all types are considered. + schema: + type: array + items: + enum: + - TASK_QUEUE_TYPE_UNSPECIFIED + - TASK_QUEUE_TYPE_WORKFLOW + - TASK_QUEUE_TYPE_ACTIVITY + - TASK_QUEUE_TYPE_NEXUS + type: string + format: enum + - name: reportPollers + in: query + description: |- + Report backlog info for the requested task queue types and versions + bool report_backlog_info = 8; + Report list of pollers for requested task queue types and versions + schema: + type: boolean + - name: reportTaskReachability + in: query + description: |- + Report task reachability for the requested versions and all task types (task reachability is not reported + per task type). schema: type: boolean responses: @@ -1035,7 +1132,9 @@ paths: tags: - WorkflowService description: |- - Fetches task reachability to determine whether a worker may be retired. + Deprecated. Use `DescribeTaskQueue`. + + Fetches task reachability to determine whether a worker may be retired. The request may specify task queues to query for or let the server fetch all task queues mapped to the given build IDs. @@ -1774,7 +1873,9 @@ components: workerVersion: allOf: - $ref: '#/components/schemas/WorkerVersionStamp' - description: Version info of the worker who processed this workflow task. + description: |- + Version info of the worker who processed this workflow task. + Deprecated. Use the info inside the corresponding ActivityTaskStartedEvent ActivityTaskCompletedEventAttributes: type: object properties: @@ -1794,7 +1895,9 @@ components: workerVersion: allOf: - $ref: '#/components/schemas/WorkerVersionStamp' - description: Version info of the worker who processed this workflow task. + description: |- + Version info of the worker who processed this workflow task. + Deprecated. Use the info inside the corresponding ActivityTaskStartedEvent ActivityTaskFailedEventAttributes: type: object properties: @@ -1826,7 +1929,9 @@ components: workerVersion: allOf: - $ref: '#/components/schemas/WorkerVersionStamp' - description: Version info of the worker who processed this workflow task. + description: |- + Version info of the worker who processed this workflow task. + Deprecated. Use the info inside the corresponding ActivityTaskStartedEvent ActivityTaskScheduledEventAttributes: type: object properties: @@ -1885,12 +1990,11 @@ components: Activities are assigned a default retry policy controlled by the service's dynamic configuration. Retries will happen up to `schedule_to_close_timeout`. To disable retries set retry_policy.maximum_attempts to 1. - useCompatibleVersion: + useWorkflowBuildId: type: boolean description: |- - If this is set, the workflow executing this command wishes to start the activity using - a version compatible with the version that this workflow most recently ran on, if such - behavior is possible. + If this is set, the activity would be assigned to the Build ID of the workflow. Otherwise, + Assignment rules of the activity's Task Queue will be used to determine the Build ID. ActivityTaskStartedEventAttributes: type: object properties: @@ -1913,6 +2017,15 @@ components: description: |- Will be set to the most recent failure details, if this task has previously failed and then been retried. + workerVersion: + allOf: + - $ref: '#/components/schemas/WorkerVersionStamp' + description: Version info of the worker to whom this task was dispatched. + buildIdRedirectCounter: + type: string + description: |- + Used by server internally to properly reapply build ID redirects to an execution + when rebuilding it from events. ActivityTaskTimedOutEventAttributes: type: object properties: @@ -2134,6 +2247,56 @@ components: BatchOperationTermination sends terminate requests to batch workflows. Keep the parameter in sync with temporal.api.workflowservice.v1.TerminateWorkflowExecutionRequest. Ignore first_execution_run_id because this is used for single workflow operation. + BuildIdAssignmentRule: + type: object + properties: + targetBuildId: + type: string + percentageRamp: + allOf: + - $ref: '#/components/schemas/RampByPercentage' + description: |- + This ramp is useful for gradual Blue/Green deployments (and similar) + where you want to send a certain portion of the traffic to the target + Build ID. + description: |- + These rules assign a Build ID to Unassigned Workflow Executions and + Activities. + + Specifically, assignment rules are applied to the following Executions or + Activities when they are scheduled in a Task Queue: + - Generally, any new Workflow Execution, except: + - When A Child Workflow or a Continue-As-New Execution inherits the + Build ID from its parent/previous execution by setting the + `inherit_build_id` flag. + - Workflow Executions started Eagerly are assigned to the Build ID of + the Starter. + - An Activity that is scheduled on a Task Queue different from the one + their Workflow runs on, unless the `use_workflow_build_id` flag is set. + + In absence of (applicable) redirect rules (`CompatibleBuildIdRedirectRule`s) + the task will be dispatched to Workers of the Build ID determined by the + assignment rules. Otherwise, the final Build ID will be determined by the + redirect rules. + + When using Worker Versioning, in the steady state, for a given Task Queue, + there should typically be exactly one assignment rule to send all Unassigned + tasks to the latest Build ID. Existence of at least one such "unconditional" + rule at all times is enforce by the system, unless the `force` flag is used + by the user when replacing/deleting these rules (for exceptional cases). + + During a deployment, one or more additional rules can be added to assign a + subset of the tasks to a new Build ID based on a "ramp percentage". + + When there are multiple assignment rules for a Task Queue, the rules are + evaluated in order, starting from index 0. The first applicable rule will be + applied and the rest will be ignored. + + In the event that no assignment rule is applicable on a task (or the Task + Queue is simply not versioned), the tasks will be sent to unversioned + workers, if available. Otherwise, they remain Unassigned, and will be + retried for assignment, or dispatch to unversioned workers, at a later time + depending on the availability of workers. BuildIdReachability: type: object properties: @@ -2444,6 +2607,35 @@ components: properties: clusterName: type: string + CompatibleBuildIdRedirectRule: + type: object + properties: + sourceBuildId: + type: string + targetBuildId: + type: string + description: |- + These rules apply to tasks assigned to a particular Build ID + (`source_build_id`) to redirect them to another *compatible* Build ID + (`target_build_id`). + + It is user's responsibility to ensure that the target Build ID is compatible + with the source Build ID (e.g. by using the Patching API). + + Most deployments are not expected to need these rules, however following + situations can greatly benefit from redirects: + - Need to move long-running Workflow Executions from an old Build ID to a + newer one. + - Need to hotfix some broken or stuck Workflow Executions. + + In steady state, redirect rules are beneficial when dealing with old + Executions ran on now-decommissioned Build IDs: + - To redirecting the Workflow Queries to the current (compatible) Build ID. + - To be able to Reset an old Execution so it can run on the current + (compatible) Build ID. + + Redirect rules can be chained, but only the last rule in the chain can have + a ramp. CompatibleVersionSet: type: object properties: @@ -2643,8 +2835,20 @@ components: type: array items: $ref: '#/components/schemas/PollerInfo' + description: |- + Deprecated. Use `versions_info.types_info.pollers` with `ENHANCED` mode instead. + Not set in `ENHANCED` mode. taskQueueStatus: - $ref: '#/components/schemas/TaskQueueStatus' + allOf: + - $ref: '#/components/schemas/TaskQueueStatus' + description: Deprecated. Not set in `ENHANCED` mode. + versionsInfo: + type: object + additionalProperties: + $ref: '#/components/schemas/TaskQueueVersionInfo' + description: |- + This map contains Task Queue information for each Build ID. Empty string as key value means unversioned. + Only set in `ENHANCED` mode. DescribeWorkflowExecutionResponse: type: object properties: @@ -2855,6 +3059,25 @@ components: Open source users can adjust this limit by setting the server's dynamic config value for `limit.reachabilityTaskQueueScan` with the caveat that this call can strain the visibility store. + description: Deprecated. Use `DescribeTaskQueue`. + GetWorkerVersioningRulesResponse: + type: object + properties: + assignmentRules: + type: array + items: + $ref: '#/components/schemas/TimestampedBuildIdAssignmentRule' + compatibleRedirectRules: + type: array + items: + $ref: '#/components/schemas/TimestampedCompatibleBuildIdRedirectRule' + conflictToken: + type: string + description: |- + This value can be passed back to UpdateWorkerVersioningRulesRequest to + ensure that the rules were not modified between this List and the Update, + which could lead to lost updates and other confusion. + format: bytes GetWorkflowExecutionHistoryResponse: type: object properties: @@ -3514,6 +3737,17 @@ components: $ref: '#/components/schemas/Failure' lastWorkerIdentity: type: string + lastIndependentlyAssignedBuildId: + type: string + description: |- + This means the activity is independently versioned and not bound to the build ID of its workflow. + The activity will use the build id in this field instead. + If the task fails and is scheduled again, the assigned build ID may change according to the latest versioning + rules. + lastWorkerVersionStamp: + allOf: + - $ref: '#/components/schemas/WorkerVersionStamp' + description: The version stamp of the worker to whom this activity was most recently dispatched PendingChildExecutionInfo: type: object properties: @@ -3699,6 +3933,13 @@ components: $ref: '#/components/schemas/Payloads' queryRejected: $ref: '#/components/schemas/QueryRejected' + RampByPercentage: + type: object + properties: + rampPercentage: + type: number + description: Acceptable range is [0,100). + format: float Range: type: object properties: @@ -4949,12 +5190,11 @@ components: $ref: '#/components/schemas/Memo' searchAttributes: $ref: '#/components/schemas/SearchAttributes' - useCompatibleVersion: + inheritBuildId: type: boolean description: |- - If this is set, the workflow executing this command wishes to start the child workflow using - a version compatible with the version that this workflow most recently ran on, if such - behavior is possible. + If this is set, the child workflow inherits the Build ID of the parent. Otherwise, the assignment + rules of the child's Task Queue will be used to independently assign a Build ID to it. StartWorkflowExecutionRequest: type: object properties: @@ -5225,6 +5465,31 @@ components: format: double taskIdBlock: $ref: '#/components/schemas/TaskIdBlock' + description: Deprecated. Use `InternalTaskQueueStatus`. This is kept until `DescribeTaskQueue` supports legacy behavior. + TaskQueueTypeInfo: + type: object + properties: + pollers: + type: array + items: + $ref: '#/components/schemas/PollerInfo' + description: Unversioned workers (with `useVersioning=false`) are reported in unversioned result even if they set a Build ID. + TaskQueueVersionInfo: + type: object + properties: + typesInfo: + type: object + additionalProperties: + $ref: '#/components/schemas/TaskQueueTypeInfo' + description: Task Queue info per Task Type. Key is the numerical value of the temporal.api.enums.v1.TaskQueueType enum. + taskReachability: + enum: + - BUILD_ID_TASK_REACHABILITY_UNSPECIFIED + - BUILD_ID_TASK_REACHABILITY_REACHABLE + - BUILD_ID_TASK_REACHABILITY_CLOSED_WORKFLOWS_ONLY + - BUILD_ID_TASK_REACHABILITY_UNREACHABLE + type: string + format: enum TerminateWorkflowExecutionRequest: type: object properties: @@ -5308,6 +5573,22 @@ components: workflowTaskCompletedEventId: type: string description: The `WORKFLOW_TASK_COMPLETED` event which this command was reported with + TimestampedBuildIdAssignmentRule: + type: object + properties: + rule: + $ref: '#/components/schemas/BuildIdAssignmentRule' + createTime: + type: string + format: date-time + TimestampedCompatibleBuildIdRedirectRule: + type: object + properties: + rule: + $ref: '#/components/schemas/CompatibleBuildIdRedirectRule' + createTime: + type: string + format: date-time TriggerImmediatelyRequest: type: object properties: @@ -5554,11 +5835,6 @@ components: description: |- An opaque whole-worker identifier. Replaces the deprecated `binary_checksum` field when this message is included in requests which previously used that. - bundleId: - type: string - description: |- - Set if the worker used a dynamically loadable bundle to process - the task. The bundle could be a WASM blob, JS bundle, etc. useVersioning: type: boolean description: |- @@ -5680,11 +5956,11 @@ components: $ref: '#/components/schemas/Memo' searchAttributes: $ref: '#/components/schemas/SearchAttributes' - useCompatibleVersion: + inheritBuildId: type: boolean description: |- - If this is set, the workflow executing this command wishes to continue as new using a version - compatible with the version that this workflow most recently ran on. + If this is set, the new execution inherits the Build ID of the current execution. Otherwise, + the assignment rules will be used to independently assign a Build ID to the new execution. WorkflowExecutionFailedEventAttributes: type: object properties: @@ -5787,6 +6063,20 @@ components: - The root workflow of all three workflows is W1. Scenario 5: Workflow W1 is reseted, creating W2. - The root workflow of W1 is W1 and the root workflow of W2 is W2. + assignedBuildId: + type: string + description: |- + The currently assigned build ID for this execution. Presence of this value means worker versioning is used + for this execution. Assigned build ID is selected based on Worker Versioning Assignment Rules + when the first workflow task of the execution is scheduled. If the first workflow task fails and is scheduled + again, the assigned build ID may change according to the latest versioning rules. + Assigned build ID can also change in the middle of a execution if Compatible Redirect Rules are applied to + this execution. + inheritedBuildId: + type: string + description: |- + Build ID inherited from a previous/parent execution. If present, assigned_build_id will be set to this, instead + of using the assignment rules. WorkflowExecutionSignaledEventAttributes: type: object properties: @@ -5924,6 +6214,7 @@ components: description: |- If this workflow intends to use anything other than the current overall default version for the queue, then we include it here. + Deprecated. use `inherited_build_id` instead completionCallbacks: type: array items: @@ -5950,6 +6241,9 @@ components: - The root workflow of all three workflows is W1. Scenario 5: Workflow W1 is reseted, creating W2. - The root workflow of W1 is W1 and the root workflow of W2 is W2. + inheritedBuildId: + type: string + description: When present, this execution is assigned to the build ID of its parent or previous execution. description: Always the first event in workflow history WorkflowExecutionTerminatedEventAttributes: type: object @@ -6131,6 +6425,7 @@ components: Version info of the worker who processed this workflow task. If present, the `build_id` field within is also used as `binary_checksum`, which may be omitted in that case (it may also be populated to preserve compatibility). + Deprecated. Use the info inside the corresponding WorkflowTaskStartedEvent sdkMetadata: allOf: - $ref: '#/components/schemas/WorkflowTaskCompletedMetadata' @@ -6269,6 +6564,7 @@ components: Version info of the worker who processed this workflow task. If present, the `build_id` field within is also used as `binary_checksum`, which may be omitted in that case (it may also be populated to preserve compatibility). + Deprecated. Use the info inside the corresponding WorkflowTaskStartedEvent WorkflowTaskScheduledEventAttributes: type: object properties: @@ -6311,6 +6607,15 @@ components: Total history size in bytes, which the workflow might use to decide when to continue-as-new regardless of the suggestion. Note that history event count is just the event id of this event, so we don't include it explicitly here. + workerVersion: + allOf: + - $ref: '#/components/schemas/WorkerVersionStamp' + description: Version info of the worker to whom this task was dispatched. + buildIdRedirectCounter: + type: string + description: |- + Used by server internally to properly reapply build ID redirects to an execution + when rebuilding it from events. WorkflowTaskTimedOutEventAttributes: type: object properties: diff --git a/temporal/api/command/v1/message.proto b/temporal/api/command/v1/message.proto index 8ffcf83d..96f51f69 100644 --- a/temporal/api/command/v1/message.proto +++ b/temporal/api/command/v1/message.proto @@ -81,10 +81,9 @@ message ScheduleActivityTaskCommandAttributes { // Request to start the activity directly bypassing matching service and worker polling // The slot for executing the activity should be reserved when setting this field to true. bool request_eager_execution = 12; - // If this is set, the workflow executing this command wishes to start the activity using - // a version compatible with the version that this workflow most recently ran on, if such - // behavior is possible. - bool use_compatible_version = 13; + // If this is set, the activity would be assigned to the Build ID of the workflow. Otherwise, + // Assignment rules of the activity's Task Queue will be used to determine the Build ID. + bool use_workflow_build_id = 13; } message RequestCancelActivityTaskCommandAttributes { @@ -193,9 +192,9 @@ message ContinueAsNewWorkflowExecutionCommandAttributes { temporal.api.common.v1.Header header = 12; temporal.api.common.v1.Memo memo = 13; temporal.api.common.v1.SearchAttributes search_attributes = 14; - // If this is set, the workflow executing this command wishes to continue as new using a version - // compatible with the version that this workflow most recently ran on. - bool use_compatible_version = 15; + // If this is set, the new execution inherits the Build ID of the current execution. Otherwise, + // the assignment rules will be used to independently assign a Build ID to the new execution. + bool inherit_build_id = 15; // `workflow_execution_timeout` is omitted as it shouldn't be overridden from within a workflow. } @@ -223,10 +222,9 @@ message StartChildWorkflowExecutionCommandAttributes { temporal.api.common.v1.Header header = 14; temporal.api.common.v1.Memo memo = 15; temporal.api.common.v1.SearchAttributes search_attributes = 16; - // If this is set, the workflow executing this command wishes to start the child workflow using - // a version compatible with the version that this workflow most recently ran on, if such - // behavior is possible. - bool use_compatible_version = 17; + // If this is set, the child workflow inherits the Build ID of the parent. Otherwise, the assignment + // rules of the child's Task Queue will be used to independently assign a Build ID to it. + bool inherit_build_id = 17; } message ProtocolMessageCommandAttributes { diff --git a/temporal/api/common/v1/message.proto b/temporal/api/common/v1/message.proto index 5df77494..8d1fd3b9 100644 --- a/temporal/api/common/v1/message.proto +++ b/temporal/api/common/v1/message.proto @@ -127,13 +127,12 @@ message WorkerVersionStamp { // An opaque whole-worker identifier. Replaces the deprecated `binary_checksum` field when this // message is included in requests which previously used that. string build_id = 1; - // Set if the worker used a dynamically loadable bundle to process - // the task. The bundle could be a WASM blob, JS bundle, etc. - string bundle_id = 2; // If set, the worker is opting in to worker versioning. Otherwise, this is used only as a // marker for workflow reset points and the BuildIDs search attribute. bool use_versioning = 3; + + // Later, may include bundle id that could be used for WASM and/or JS dynamically loadable bundles. } // Identifies the version(s) that a worker is compatible with when polling or identifying itself, diff --git a/temporal/api/enums/v1/task_queue.proto b/temporal/api/enums/v1/task_queue.proto index 2f46cc47..c68949fe 100644 --- a/temporal/api/enums/v1/task_queue.proto +++ b/temporal/api/enums/v1/task_queue.proto @@ -62,6 +62,7 @@ enum TaskQueueType { // Specifies which category of tasks may reach a worker on a versioned task queue. // Used both in a reachability query and its response. +// Deprecated. enum TaskReachability { TASK_REACHABILITY_UNSPECIFIED = 0; // There's a possiblity for a worker to receive new workflow tasks. Workers should *not* be retired. @@ -78,3 +79,30 @@ enum TaskReachability { TASK_REACHABILITY_CLOSED_WORKFLOWS = 4; } +// Specifies which category of tasks may reach a versioned worker of a certain Build ID. +// Note: future activities who inherit their workflow's Build ID but not its Task Queue will not be +// accounted for reachability as server cannot not know if they'll happen as they do not use +// assignment rules of their Task Queue. Same goes for Child Workflows or Continue-As-New Workflows +// who inherit the parent/previous workflow's Build ID but not its Task Queue. In those cases, make +// sure to query reachability for the parent/previous workflow's Task Queue as well. +enum BuildIdTaskReachability { + // Task reachability is not reported + BUILD_ID_TASK_REACHABILITY_UNSPECIFIED = 0; + // Build ID may be used by new workflows or activities (base on versioning rules), or there are + // open workflows or backlogged activities assigned to it. + BUILD_ID_TASK_REACHABILITY_REACHABLE = 1; + // Build ID does not have open workflows and is not reachable by new workflows, + // but MAY have closed workflows within the namespace retention period. + // Not applicable to activity-only task queues. + BUILD_ID_TASK_REACHABILITY_CLOSED_WORKFLOWS_ONLY = 2; + // Build ID is not used for new executions, nor it has been used by any existing execution + // within the retention period. + BUILD_ID_TASK_REACHABILITY_UNREACHABLE = 3; +} + +enum DescribeTaskQueueMode { + // Unspecified means legacy behavior. + DESCRIBE_TASK_QUEUE_MODE_UNSPECIFIED = 0; + // Enhanced mode reports aggregated results for all partitions, supports Build IDs, and reports richer info. + DESCRIBE_TASK_QUEUE_MODE_ENHANCED = 1; +} diff --git a/temporal/api/history/v1/message.proto b/temporal/api/history/v1/message.proto index edf2eba4..57371425 100644 --- a/temporal/api/history/v1/message.proto +++ b/temporal/api/history/v1/message.proto @@ -103,8 +103,8 @@ message WorkflowExecutionStartedEventAttributes { string workflow_id = 28; // If this workflow intends to use anything other than the current overall default version for // the queue, then we include it here. + // Deprecated. use `inherited_build_id` instead temporal.api.common.v1.WorkerVersionStamp source_version_stamp = 29; - // Completion callbacks attached when this workflow was started. repeated temporal.api.common.v1.Callback completion_callbacks = 30; @@ -126,6 +126,8 @@ message WorkflowExecutionStartedEventAttributes { // Scenario 5: Workflow W1 is reseted, creating W2. // - The root workflow of W1 is W1 and the root workflow of W2 is W2. temporal.api.common.v1.WorkflowExecution root_workflow_execution = 31; + // When present, this execution is assigned to the build ID of its parent or previous execution. + string inherited_build_id = 32; } message WorkflowExecutionCompletedEventAttributes { @@ -178,9 +180,9 @@ message WorkflowExecutionContinuedAsNewEventAttributes { temporal.api.common.v1.Header header = 12; temporal.api.common.v1.Memo memo = 13; temporal.api.common.v1.SearchAttributes search_attributes = 14; - // If this is set, the workflow executing this command wishes to continue as new using a version - // compatible with the version that this workflow most recently ran on. - bool use_compatible_version = 15; + // If this is set, the new execution inherits the Build ID of the current execution. Otherwise, + // the assignment rules will be used to independently assign a Build ID to the new execution. + bool inherit_build_id = 15; // workflow_execution_timeout is omitted as it shouldn't be overridden from within a workflow. } @@ -211,6 +213,11 @@ message WorkflowTaskStartedEventAttributes { // continue-as-new regardless of the suggestion. Note that history event count is // just the event id of this event, so we don't include it explicitly here. int64 history_size_bytes = 5; + // Version info of the worker to whom this task was dispatched. + temporal.api.common.v1.WorkerVersionStamp worker_version = 6; + // Used by server internally to properly reapply build ID redirects to an execution + // when rebuilding it from events. + int64 build_id_redirect_counter = 7; } message WorkflowTaskCompletedEventAttributes { @@ -225,6 +232,7 @@ message WorkflowTaskCompletedEventAttributes { // Version info of the worker who processed this workflow task. If present, the `build_id` field // within is also used as `binary_checksum`, which may be omitted in that case (it may also be // populated to preserve compatibility). + // Deprecated. Use the info inside the corresponding WorkflowTaskStartedEvent temporal.api.common.v1.WorkerVersionStamp worker_version = 5; // Data the SDK wishes to record for itself, but server need not interpret, and does not // directly impact workflow state. @@ -264,6 +272,7 @@ message WorkflowTaskFailedEventAttributes { // Version info of the worker who processed this workflow task. If present, the `build_id` field // within is also used as `binary_checksum`, which may be omitted in that case (it may also be // populated to preserve compatibility). + // Deprecated. Use the info inside the corresponding WorkflowTaskStartedEvent temporal.api.common.v1.WorkerVersionStamp worker_version = 10; } @@ -305,10 +314,9 @@ message ActivityTaskScheduledEventAttributes { // configuration. Retries will happen up to `schedule_to_close_timeout`. To disable retries set // retry_policy.maximum_attempts to 1. temporal.api.common.v1.RetryPolicy retry_policy = 12; - // If this is set, the workflow executing this command wishes to start the activity using - // a version compatible with the version that this workflow most recently ran on, if such - // behavior is possible. - bool use_compatible_version = 13; + // If this is set, the activity would be assigned to the Build ID of the workflow. Otherwise, + // Assignment rules of the activity's Task Queue will be used to determine the Build ID. + bool use_workflow_build_id = 13; } message ActivityTaskStartedEventAttributes { @@ -323,6 +331,11 @@ message ActivityTaskStartedEventAttributes { // Will be set to the most recent failure details, if this task has previously failed and then // been retried. temporal.api.failure.v1.Failure last_failure = 5; + // Version info of the worker to whom this task was dispatched. + temporal.api.common.v1.WorkerVersionStamp worker_version = 6; + // Used by server internally to properly reapply build ID redirects to an execution + // when rebuilding it from events. + int64 build_id_redirect_counter = 7; } message ActivityTaskCompletedEventAttributes { @@ -335,6 +348,7 @@ message ActivityTaskCompletedEventAttributes { // id of the worker that completed this task string identity = 4; // Version info of the worker who processed this workflow task. + // Deprecated. Use the info inside the corresponding ActivityTaskStartedEvent temporal.api.common.v1.WorkerVersionStamp worker_version = 5; } @@ -349,6 +363,7 @@ message ActivityTaskFailedEventAttributes { string identity = 4; temporal.api.enums.v1.RetryState retry_state = 5; // Version info of the worker who processed this workflow task. + // Deprecated. Use the info inside the corresponding ActivityTaskStartedEvent temporal.api.common.v1.WorkerVersionStamp worker_version = 6; } @@ -383,6 +398,7 @@ message ActivityTaskCanceledEventAttributes { // id of the worker who canceled this activity string identity = 5; // Version info of the worker who processed this workflow task. + // Deprecated. Use the info inside the corresponding ActivityTaskStartedEvent temporal.api.common.v1.WorkerVersionStamp worker_version = 6; } @@ -603,10 +619,9 @@ message StartChildWorkflowExecutionInitiatedEventAttributes { temporal.api.common.v1.Header header = 15; temporal.api.common.v1.Memo memo = 16; temporal.api.common.v1.SearchAttributes search_attributes = 17; - // If this is set, the workflow executing this command wishes to start the child workflow using - // a version compatible with the version that this workflow most recently ran on, if such - // behavior is possible. - bool use_compatible_version = 19; + // If this is set, the child workflow inherits the Build ID of the parent. Otherwise, the assignment + // rules of the child's Task Queue will be used to independently assign a Build ID to it. + bool inherit_build_id = 19; } message StartChildWorkflowExecutionFailedEventAttributes { diff --git a/temporal/api/taskqueue/v1/message.proto b/temporal/api/taskqueue/v1/message.proto index 7e6359ec..bd9b4822 100644 --- a/temporal/api/taskqueue/v1/message.proto +++ b/temporal/api/taskqueue/v1/message.proto @@ -54,6 +54,29 @@ message TaskQueueMetadata { google.protobuf.DoubleValue max_tasks_per_second = 1; } +// Used for specifying versions the caller is interested in. +message TaskQueueVersionSelection { + // Include specific Build IDs. + repeated string build_ids = 1; + // Include the unversioned queue. + bool unversioned = 2; + // Include all active versions. A version is considered active if it has had new + // tasks or polls recently. + bool all_active = 3; +} + +message TaskQueueVersionInfo { + // Task Queue info per Task Type. Key is the numerical value of the temporal.api.enums.v1.TaskQueueType enum. + map types_info = 1; + temporal.api.enums.v1.BuildIdTaskReachability task_reachability = 2; +} + +message TaskQueueTypeInfo { + // Unversioned workers (with `useVersioning=false`) are reported in unversioned result even if they set a Build ID. + repeated PollerInfo pollers = 1; +} + +// Deprecated. Use `InternalTaskQueueStatus`. This is kept until `DescribeTaskQueue` supports legacy behavior. message TaskQueueStatus { int64 backlog_count_hint = 1; int64 read_level = 2; @@ -111,3 +134,96 @@ message BuildIdReachability { // Reachability per task queue. repeated TaskQueueReachability task_queue_reachability = 2; } + +message RampByPercentage { + // Acceptable range is [0,100). + float ramp_percentage = 1; +} + +// These rules assign a Build ID to Unassigned Workflow Executions and +// Activities. +// +// Specifically, assignment rules are applied to the following Executions or +// Activities when they are scheduled in a Task Queue: +// - Generally, any new Workflow Execution, except: +// - When A Child Workflow or a Continue-As-New Execution inherits the +// Build ID from its parent/previous execution by setting the +// `inherit_build_id` flag. +// - Workflow Executions started Eagerly are assigned to the Build ID of +// the Starter. +// - An Activity that is scheduled on a Task Queue different from the one +// their Workflow runs on, unless the `use_workflow_build_id` flag is set. +// +// In absence of (applicable) redirect rules (`CompatibleBuildIdRedirectRule`s) +// the task will be dispatched to Workers of the Build ID determined by the +// assignment rules. Otherwise, the final Build ID will be determined by the +// redirect rules. +// +// When using Worker Versioning, in the steady state, for a given Task Queue, +// there should typically be exactly one assignment rule to send all Unassigned +// tasks to the latest Build ID. Existence of at least one such "unconditional" +// rule at all times is enforce by the system, unless the `force` flag is used +// by the user when replacing/deleting these rules (for exceptional cases). +// +// During a deployment, one or more additional rules can be added to assign a +// subset of the tasks to a new Build ID based on a "ramp percentage". +// +// When there are multiple assignment rules for a Task Queue, the rules are +// evaluated in order, starting from index 0. The first applicable rule will be +// applied and the rest will be ignored. +// +// In the event that no assignment rule is applicable on a task (or the Task +// Queue is simply not versioned), the tasks will be sent to unversioned +// workers, if available. Otherwise, they remain Unassigned, and will be +// retried for assignment, or dispatch to unversioned workers, at a later time +// depending on the availability of workers. +message BuildIdAssignmentRule { + string target_build_id = 1; + + // If a ramp is provided, this rule will be applied only to a sample of + // tasks according to the provided percentage. + // This option can be used only on "terminal" Build IDs (the ones not used + // as source in any redirect rules). + oneof ramp { + // This ramp is useful for gradual Blue/Green deployments (and similar) + // where you want to send a certain portion of the traffic to the target + // Build ID. + RampByPercentage percentage_ramp = 3; + } +} + +// These rules apply to tasks assigned to a particular Build ID +// (`source_build_id`) to redirect them to another *compatible* Build ID +// (`target_build_id`). +// +// It is user's responsibility to ensure that the target Build ID is compatible +// with the source Build ID (e.g. by using the Patching API). +// +// Most deployments are not expected to need these rules, however following +// situations can greatly benefit from redirects: +// - Need to move long-running Workflow Executions from an old Build ID to a +// newer one. +// - Need to hotfix some broken or stuck Workflow Executions. +// +// In steady state, redirect rules are beneficial when dealing with old +// Executions ran on now-decommissioned Build IDs: +// - To redirecting the Workflow Queries to the current (compatible) Build ID. +// - To be able to Reset an old Execution so it can run on the current +// (compatible) Build ID. +// +// Redirect rules can be chained, but only the last rule in the chain can have +// a ramp. +message CompatibleBuildIdRedirectRule { + string source_build_id = 1; + string target_build_id = 2; +} + +message TimestampedBuildIdAssignmentRule { + BuildIdAssignmentRule rule = 1; + google.protobuf.Timestamp create_time = 2; +} + +message TimestampedCompatibleBuildIdRedirectRule { + CompatibleBuildIdRedirectRule rule = 1; + google.protobuf.Timestamp create_time = 2; +} \ No newline at end of file diff --git a/temporal/api/workflow/v1/message.proto b/temporal/api/workflow/v1/message.proto index 3cec387f..1da75bbd 100644 --- a/temporal/api/workflow/v1/message.proto +++ b/temporal/api/workflow/v1/message.proto @@ -32,6 +32,7 @@ option ruby_package = "Temporalio::Api::Workflow::V1"; option csharp_namespace = "Temporalio.Api.Workflow.V1"; import "google/protobuf/duration.proto"; +import "google/protobuf/empty.proto"; import "google/protobuf/timestamp.proto"; import "temporal/api/enums/v1/common.proto"; @@ -79,6 +80,16 @@ message WorkflowExecutionInfo { // Scenario 5: Workflow W1 is reseted, creating W2. // - The root workflow of W1 is W1 and the root workflow of W2 is W2. temporal.api.common.v1.WorkflowExecution root_execution = 18; + // The currently assigned build ID for this execution. Presence of this value means worker versioning is used + // for this execution. Assigned build ID is selected based on Worker Versioning Assignment Rules + // when the first workflow task of the execution is scheduled. If the first workflow task fails and is scheduled + // again, the assigned build ID may change according to the latest versioning rules. + // Assigned build ID can also change in the middle of a execution if Compatible Redirect Rules are applied to + // this execution. + string assigned_build_id = 19; + // Build ID inherited from a previous/parent execution. If present, assigned_build_id will be set to this, instead + // of using the assignment rules. + string inherited_build_id = 20; } message WorkflowExecutionConfig { @@ -101,6 +112,20 @@ message PendingActivityInfo { google.protobuf.Timestamp expiration_time = 10; temporal.api.failure.v1.Failure last_failure = 11; string last_worker_identity = 12; + // Absence of `assigned_build_id` generally means this task is on an "unversioned" task queue. + // In rare cases, it can also mean that the task queue is versioned but we failed to write activity's + // independently-assigned build ID to the database. This case heals automatically once the task is dispatched. + oneof assigned_build_id { + // When present, it means this activity is assigned to the build ID of its workflow. + google.protobuf.Empty use_workflow_build_id = 13; + // This means the activity is independently versioned and not bound to the build ID of its workflow. + // The activity will use the build id in this field instead. + // If the task fails and is scheduled again, the assigned build ID may change according to the latest versioning + // rules. + string last_independently_assigned_build_id = 14; + } + // The version stamp of the worker to whom this activity was most recently dispatched + temporal.api.common.v1.WorkerVersionStamp last_worker_version_stamp = 15; } message PendingChildExecutionInfo { diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index c2d693b1..f3742e89 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -878,17 +878,48 @@ message DescribeWorkflowExecutionResponse { repeated temporal.api.workflow.v1.CallbackInfo callbacks = 6; } +// (-- api-linter: core::0203::optional=disabled +// aip.dev/not-precedent: field_behavior annotation not available in our gogo fork --) message DescribeTaskQueueRequest { string namespace = 1; + // Sticky queues are not supported in `ENHANCED` mode. temporal.api.taskqueue.v1.TaskQueue task_queue = 2; + // Deprecated. Use `ENHANCED` mode with `task_queue_types`. Ignored in `ENHANCED` mode. // If unspecified (TASK_QUEUE_TYPE_UNSPECIFIED), then default value (TASK_QUEUE_TYPE_WORKFLOW) will be used. temporal.api.enums.v1.TaskQueueType task_queue_type = 3; + // Deprecated. Ignored in `ENHANCED` mode. bool include_task_queue_status = 4; + + // All options except `task_queue_type` and `include_task_queue_status` are only available in the `ENHANCED` mode. + temporal.api.enums.v1.DescribeTaskQueueMode api_mode = 5; + + // Optional. If not provided, the result for the default Build ID will be returned. The default Build ID is the one + // mentioned in the first unconditional Assignment Rule. If there is no default Build ID, the result for the + // unversioned queue will be returned. + // (-- api-linter: core::0140::prepositions --) + temporal.api.taskqueue.v1.TaskQueueVersionSelection versions = 6; + + // Task queue types to report info about. If not specified, all types are considered. + repeated temporal.api.enums.v1.TaskQueueType task_queue_types = 7; + // Report backlog info for the requested task queue types and versions + // bool report_backlog_info = 8; + // Report list of pollers for requested task queue types and versions + bool report_pollers = 9; + // Report task reachability for the requested versions and all task types (task reachability is not reported + // per task type). + bool report_task_reachability = 10; } message DescribeTaskQueueResponse { + // Deprecated. Use `versions_info.types_info.pollers` with `ENHANCED` mode instead. + // Not set in `ENHANCED` mode. repeated temporal.api.taskqueue.v1.PollerInfo pollers = 1; + // Deprecated. Not set in `ENHANCED` mode. temporal.api.taskqueue.v1.TaskQueueStatus task_queue_status = 2; + + // This map contains Task Queue information for each Build ID. Empty string as key value means unversioned. + // Only set in `ENHANCED` mode. + map versions_info = 3; } message GetClusterInfoRequest { @@ -1178,6 +1209,127 @@ message GetWorkerBuildIdCompatibilityResponse { repeated temporal.api.taskqueue.v1.CompatibleVersionSet major_version_sets = 1; } +// (-- api-linter: core::0134::request-mask-required=disabled +// aip.dev/not-precedent: UpdateNamespace RPC doesn't follow Google API format. --) +// (-- api-linter: core::0134::request-resource-required=disabled +// aip.dev/not-precedent: GetWorkerBuildIdCompatibilityRequest RPC doesn't follow Google API format. --) +message UpdateWorkerVersioningRulesRequest { + // Inserts the rule to the list of assignment rules for this Task Queue. + // The rules are evaluated in order, starting from index 0. The first + // applicable rule will be applied and the rest will be ignored. + message InsertBuildIdAssignmentRule { + // Use this option to insert the rule in a particular index. By + // default, the new rule is inserted at the beginning of the list + // (index 0). If the given index is too larger the rule will be + // inserted at the end of the list. + int32 rule_index = 1; + temporal.api.taskqueue.v1.BuildIdAssignmentRule rule = 2; + } + + // Replaces the assignment rule at a given index. + message ReplaceBuildIdAssignmentRule { + int32 rule_index = 1; + temporal.api.taskqueue.v1.BuildIdAssignmentRule rule = 2; + + // By default presence of one unconditional rule is enforced, otherwise + // the replace operation will be rejected. Set `force` to true to + // bypass this validation. An unconditional assignment rule: + // - Has no hint filter + // - Has no ramp + bool force = 3; + } + + message DeleteBuildIdAssignmentRule { + int32 rule_index = 1; + + // By default presence of one unconditional rule is enforced, otherwise + // the delete operation will be rejected. Set `force` to true to + // bypass this validation. An unconditional assignment rule: + // - Has no hint filter + // - Has no ramp + bool force = 2; + } + + // Adds the rule to the list of redirect rules for this Task Queue. There + // can be at most one redirect rule for each distinct Source Build ID. + message AddCompatibleBuildIdRedirectRule { + temporal.api.taskqueue.v1.CompatibleBuildIdRedirectRule rule = 1; + } + + // Replaces the routing rule with the given source Build ID. + message ReplaceCompatibleBuildIdRedirectRule { + temporal.api.taskqueue.v1.CompatibleBuildIdRedirectRule rule = 1; + } + + message DeleteCompatibleBuildIdRedirectRule { + string source_build_id = 1; + } + + // This command is intended to be used to complete the rollout of a Build + // ID and cleanup unnecessary rules possibly created during a gradual + // rollout. Specifically, this command will make the following changes + // atomically: + // 1. Adds an assignment rule (with full ramp) for the target Build ID at + // the end of the list. + // 2. Removes all previously added assignment rules to the given target + // Build ID (if any). + // 3. Removes any fully-ramped assignment rule for other Build IDs. + message CommitBuildId { + string target_build_id = 1; + + // To prevent committing invalid Build IDs, we reject the request if no + // pollers has been seen recently for this Build ID. Use the `force` + // option to disable this validation. + bool force = 2; + } + + string namespace = 1; + string task_queue = 2; + + // A valid conflict_token can be taken from the previous + // ListWorkerVersioningRulesResponse or UpdateWorkerVersioningRulesResponse. + // An invalid token will cause this request to fail, ensuring that if the rules + // for this Task Queue have been modified between the previous and current + // operation, the request will fail instead of causing an unpredictable mutation. + bytes conflict_token = 3; + + oneof operation { + InsertBuildIdAssignmentRule insert_assignment_rule = 4; + ReplaceBuildIdAssignmentRule replace_assignment_rule = 5; + DeleteBuildIdAssignmentRule delete_assignment_rule = 6; + AddCompatibleBuildIdRedirectRule add_compatible_redirect_rule = 7; + ReplaceCompatibleBuildIdRedirectRule replace_compatible_redirect_rule = 8; + DeleteCompatibleBuildIdRedirectRule delete_compatible_redirect_rule = 9; + CommitBuildId commit_build_id = 10; + } +} + +message UpdateWorkerVersioningRulesResponse { + repeated temporal.api.taskqueue.v1.TimestampedBuildIdAssignmentRule assignment_rules = 1; + repeated temporal.api.taskqueue.v1.TimestampedCompatibleBuildIdRedirectRule compatible_redirect_rules = 2; + + // This value can be passed back to UpdateWorkerVersioningRulesRequest to + // ensure that the rules were not modified between the two updates, which + // could lead to lost updates and other confusion. + bytes conflict_token = 3; +} + +message GetWorkerVersioningRulesRequest { + string namespace = 1; + string task_queue = 2; +} + +message GetWorkerVersioningRulesResponse { + repeated temporal.api.taskqueue.v1.TimestampedBuildIdAssignmentRule assignment_rules = 1; + repeated temporal.api.taskqueue.v1.TimestampedCompatibleBuildIdRedirectRule compatible_redirect_rules = 2; + + // This value can be passed back to UpdateWorkerVersioningRulesRequest to + // ensure that the rules were not modified between this List and the Update, + // which could lead to lost updates and other confusion. + bytes conflict_token = 3; +} + +// Deprecated. Use `DescribeTaskQueue`. message GetWorkerTaskReachabilityRequest { string namespace = 1; // Build ids to retrieve reachability for. An empty string will be interpreted as an unversioned worker. @@ -1202,6 +1354,7 @@ message GetWorkerTaskReachabilityRequest { temporal.api.enums.v1.TaskReachability reachability = 4; } +// Deprecated. Use `DescribeTaskQueue`. message GetWorkerTaskReachabilityResponse { // Task reachability, broken down by build id and then task queue. // When requesting a large number of task queues or all task queues associated with the given build ids in a diff --git a/temporal/api/workflowservice/v1/service.proto b/temporal/api/workflowservice/v1/service.proto index 90a99fd4..8d81eea9 100644 --- a/temporal/api/workflowservice/v1/service.proto +++ b/temporal/api/workflowservice/v1/service.proto @@ -436,7 +436,10 @@ service WorkflowService { }; } - // DescribeTaskQueue returns information about the target task queue. + // DescribeTaskQueue returns the following information about the target task queue, broken down by Build ID: + // - List of pollers + // - Workflow Reachability status + // - Backlog info for Workflow and/or Activity tasks rpc DescribeTaskQueue (DescribeTaskQueueRequest) returns (DescribeTaskQueueResponse) { option (google.api.http) = { get: "/api/v1/namespaces/{namespace}/task-queues/{task_queue.name}" @@ -514,6 +517,8 @@ service WorkflowService { }; } + // Deprecated. Use `UpdateWorkerVersioningRules`. + // // Allows users to specify sets of worker build id versions on a per task queue basis. Versions // are ordered, and may be either compatible with some extant version, or a new incompatible // version, forming sets of ids which are incompatible with each other, but whose contained @@ -531,6 +536,7 @@ service WorkflowService { // aip.dev/not-precedent: We do yet expose versioning API to HTTP. --) rpc UpdateWorkerBuildIdCompatibility (UpdateWorkerBuildIdCompatibilityRequest) returns (UpdateWorkerBuildIdCompatibilityResponse) {} + // Deprecated. Use `GetWorkerVersioningRules`. // Fetches the worker build id versioning sets for a task queue. rpc GetWorkerBuildIdCompatibility (GetWorkerBuildIdCompatibilityRequest) returns (GetWorkerBuildIdCompatibilityResponse) { option (google.api.http) = { @@ -538,6 +544,22 @@ service WorkflowService { }; } + // Allows updating the Build ID assignment and redirect rules for a given Task Queue. + // WARNING: Worker Versioning is not yet stable and the API and behavior may change incompatibly. + // (-- api-linter: core::0127::http-annotation=disabled + // aip.dev/not-precedent: We do yet expose versioning API to HTTP. --) + rpc UpdateWorkerVersioningRules (UpdateWorkerVersioningRulesRequest) returns (UpdateWorkerVersioningRulesResponse) {} + + // Fetches the Build ID assignment and redirect rules for a Task Queue. + // WARNING: Worker Versioning is not yet stable and the API and behavior may change incompatibly. + rpc GetWorkerVersioningRules (GetWorkerVersioningRulesRequest) returns (GetWorkerVersioningRulesResponse) { + option (google.api.http) = { + get: "/api/v1/namespaces/{namespace}/task-queues/{task_queue}/worker-versioning-rules" + }; + } + + // Deprecated. Use `DescribeTaskQueue`. + // // Fetches task reachability to determine whether a worker may be retired. // The request may specify task queues to query for or let the server fetch all task queues mapped to the given // build IDs.