From 59f9bc3b8ff03defeb96d14a0a462eb9f8bcb74e Mon Sep 17 00:00:00 2001 From: Dan Davison Date: Wed, 22 Oct 2025 07:25:22 -0400 Subject: [PATCH 1/4] Unify Describe and GetResult --- openapi/openapiv2.json | 202 ++++++----------- openapi/openapiv3.yaml | 205 ++++++------------ .../workflowservice/v1/request_response.proto | 79 ++++--- temporal/api/workflowservice/v1/service.proto | 28 +-- 4 files changed, 195 insertions(+), 319 deletions(-) diff --git a/openapi/openapiv2.json b/openapi/openapiv2.json index 97c2a1f6c..c38495d95 100644 --- a/openapi/openapiv2.json +++ b/openapi/openapiv2.json @@ -859,13 +859,14 @@ }, "/api/v1/namespaces/{namespace}/activities/{activityId}": { "get": { - "summary": "DescribeActivityExecution returns information about the specified activity execution.\nPass in a long_poll_token to turn this request into a long poll that gets unblocked when the activity makes\nprogress.\nIn case the activity has not made progress by the time the long poll request times out, an empty response is\nreturned and the caller may issue an identical DescribeActivityExecution request to continue polling.", - "operationId": "DescribeActivityExecution2", + "summary": "GetActivityExecutionStatus returns the status and/or outcome of an activity execution.\nThis unified endpoint can:\n- Get current activity info synchronously (when include_info is true)\n- Long poll for activity info updates (when wait_info is true)\n- Get activity outcome synchronously if completed (when include_outcome is true)\n- Long poll for activity completion (when wait_outcome is true)", + "description": "This replaces both DescribeActivityExecution and GetActivityExecutionResult with a single\nflexible endpoint that can handle both synchronous queries and long polling for both\ninfo updates and completion.", + "operationId": "GetActivityExecutionStatus2", "responses": { "200": { "description": "A successful response.", "schema": { - "$ref": "#/definitions/v1DescribeActivityExecutionResponse" + "$ref": "#/definitions/v1GetActivityExecutionStatusResponse" } }, "default": { @@ -890,21 +891,31 @@ }, { "name": "runId", - "description": "Activity run ID, targets the latest run if run_id is empty.", "in": "query", "required": false, "type": "string" }, { - "name": "includeInput", - "description": "If true, the activity input is returned in the response.", + "name": "includeInfo.includeInput", "in": "query", "required": false, "type": "boolean" }, { - "name": "longPollToken", - "description": "If not empty, turns this request into a long poll that is unblocked when the activity state changes from the time\nthe token was returned.\nThis token is returned as part of the `DescribeActivityExecutionResponse`.", + "name": "noWait", + "in": "query", + "required": false, + "type": "object" + }, + { + "name": "waitAnyStateChange.longPollToken", + "in": "query", + "required": false, + "type": "string", + "format": "byte" + }, + { + "name": "waitCompletion.longPollToken", "in": "query", "required": false, "type": "string", @@ -1006,57 +1017,6 @@ ] } }, - "/api/v1/namespaces/{namespace}/activities/{activityId}/result": { - "get": { - "summary": "GetActivityExecutionResult returns the activity result if it is in a terminal status or (optionally) wait for it\nto reach one.", - "operationId": "GetActivityExecutionResult2", - "responses": { - "200": { - "description": "A successful response.", - "schema": { - "$ref": "#/definitions/v1GetActivityExecutionResultResponse" - } - }, - "default": { - "description": "An unexpected error response.", - "schema": { - "$ref": "#/definitions/rpcStatus" - } - } - }, - "parameters": [ - { - "name": "namespace", - "in": "path", - "required": true, - "type": "string" - }, - { - "name": "activityId", - "in": "path", - "required": true, - "type": "string" - }, - { - "name": "runId", - "description": "Activity run ID, targets the latest run if run_id is empty.", - "in": "query", - "required": false, - "type": "string" - }, - { - "name": "wait", - "description": "If set, turns this request into a long poll that is unblocked when the activity reaches a terminal status.\nThe wait duration is capped by the request's context deadline or by the maximum enforced long poll interval\nallowed by the server.", - "in": "query", - "required": false, - "type": "boolean" - } - ], - "tags": [ - "WorkflowService" - ] - } - }, "/api/v1/namespaces/{namespace}/activities/{activityId}/terminate": { "post": { "summary": "TerminateActivityExecution terminates an existing activity execution immediately.", @@ -5474,13 +5434,14 @@ }, "/namespaces/{namespace}/activities/{activityId}": { "get": { - "summary": "DescribeActivityExecution returns information about the specified activity execution.\nPass in a long_poll_token to turn this request into a long poll that gets unblocked when the activity makes\nprogress.\nIn case the activity has not made progress by the time the long poll request times out, an empty response is\nreturned and the caller may issue an identical DescribeActivityExecution request to continue polling.", - "operationId": "DescribeActivityExecution", + "summary": "GetActivityExecutionStatus returns the status and/or outcome of an activity execution.\nThis unified endpoint can:\n- Get current activity info synchronously (when include_info is true)\n- Long poll for activity info updates (when wait_info is true)\n- Get activity outcome synchronously if completed (when include_outcome is true)\n- Long poll for activity completion (when wait_outcome is true)", + "description": "This replaces both DescribeActivityExecution and GetActivityExecutionResult with a single\nflexible endpoint that can handle both synchronous queries and long polling for both\ninfo updates and completion.", + "operationId": "GetActivityExecutionStatus", "responses": { "200": { "description": "A successful response.", "schema": { - "$ref": "#/definitions/v1DescribeActivityExecutionResponse" + "$ref": "#/definitions/v1GetActivityExecutionStatusResponse" } }, "default": { @@ -5505,21 +5466,31 @@ }, { "name": "runId", - "description": "Activity run ID, targets the latest run if run_id is empty.", "in": "query", "required": false, "type": "string" }, { - "name": "includeInput", - "description": "If true, the activity input is returned in the response.", + "name": "includeInfo.includeInput", "in": "query", "required": false, "type": "boolean" }, { - "name": "longPollToken", - "description": "If not empty, turns this request into a long poll that is unblocked when the activity state changes from the time\nthe token was returned.\nThis token is returned as part of the `DescribeActivityExecutionResponse`.", + "name": "noWait", + "in": "query", + "required": false, + "type": "object" + }, + { + "name": "waitAnyStateChange.longPollToken", + "in": "query", + "required": false, + "type": "string", + "format": "byte" + }, + { + "name": "waitCompletion.longPollToken", "in": "query", "required": false, "type": "string", @@ -5621,57 +5592,6 @@ ] } }, - "/namespaces/{namespace}/activities/{activityId}/result": { - "get": { - "summary": "GetActivityExecutionResult returns the activity result if it is in a terminal status or (optionally) wait for it\nto reach one.", - "operationId": "GetActivityExecutionResult", - "responses": { - "200": { - "description": "A successful response.", - "schema": { - "$ref": "#/definitions/v1GetActivityExecutionResultResponse" - } - }, - "default": { - "description": "An unexpected error response.", - "schema": { - "$ref": "#/definitions/rpcStatus" - } - } - }, - "parameters": [ - { - "name": "namespace", - "in": "path", - "required": true, - "type": "string" - }, - { - "name": "activityId", - "in": "path", - "required": true, - "type": "string" - }, - { - "name": "runId", - "description": "Activity run ID, targets the latest run if run_id is empty.", - "in": "query", - "required": false, - "type": "string" - }, - { - "name": "wait", - "description": "If set, turns this request into a long poll that is unblocked when the activity reaches a terminal status.\nThe wait duration is capped by the request's context deadline or by the maximum enforced long poll interval\nallowed by the server.", - "in": "query", - "required": false, - "type": "boolean" - } - ], - "tags": [ - "WorkflowService" - ] - } - }, "/namespaces/{namespace}/activities/{activityId}/terminate": { "post": { "summary": "TerminateActivityExecution terminates an existing activity execution immediately.", @@ -8863,6 +8783,26 @@ } } }, + "GetActivityExecutionStatusRequestIncludeInfoOptions": { + "type": "object", + "properties": { + "includeInput": { + "type": "boolean" + } + } + }, + "GetActivityExecutionStatusRequestIncludeOutcomeOptions": { + "type": "object" + }, + "GetActivityExecutionStatusRequestWaitOptions": { + "type": "object", + "properties": { + "longPollToken": { + "type": "string", + "format": "byte" + } + } + }, "LinkActivity": { "type": "object", "properties": { @@ -12858,19 +12798,6 @@ "type": "object", "description": "Deprecated." }, - "v1DescribeActivityExecutionResponse": { - "type": "object", - "properties": { - "info": { - "$ref": "#/definitions/v1ActivityExecutionInfo" - }, - "longPollToken": { - "type": "string", - "format": "byte", - "description": "A token that can be passed in via a subsequent `DescribeActivityExecutionRequest` to long poll on the activity\nstate as it makes progress." - } - } - }, "v1DescribeBatchOperationResponse": { "type": "object", "properties": { @@ -13367,12 +13294,16 @@ } } }, - "v1GetActivityExecutionResultResponse": { + "v1GetActivityExecutionStatusResponse": { "type": "object", "properties": { "runId": { "type": "string", - "description": "The run ID of the completed activity, may be used in case a run ID was not specified in the request." + "description": "The run ID of the activity, useful when run_id was not specified in the request." + }, + "info": { + "$ref": "#/definitions/v1ActivityExecutionInfo", + "description": "Only set if include_info was present in the request." }, "result": { "$ref": "#/definitions/v1Payloads", @@ -13381,6 +13312,11 @@ "failure": { "$ref": "#/definitions/apifailurev1Failure", "description": "The failure if the activity completed unsuccessfully." + }, + "stateChangeLongPollToken": { + "type": "string", + "format": "byte", + "description": "Token to use for a follow-on request using wait_any_state_change.\nOnly set if wait_policy was wait_any_state_change and the activity is not complete." } } }, diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index 5467c53be..071ae6bdf 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -827,12 +827,17 @@ paths: tags: - WorkflowService description: |- - DescribeActivityExecution returns information about the specified activity execution. - Pass in a long_poll_token to turn this request into a long poll that gets unblocked when the activity makes - progress. - In case the activity has not made progress by the time the long poll request times out, an empty response is - returned and the caller may issue an identical DescribeActivityExecution request to continue polling. - operationId: DescribeActivityExecution + GetActivityExecutionStatus returns the status and/or outcome of an activity execution. + This unified endpoint can: + - Get current activity info synchronously (when include_info is true) + - Long poll for activity info updates (when wait_info is true) + - Get activity outcome synchronously if completed (when include_outcome is true) + - Long poll for activity completion (when wait_outcome is true) + + This replaces both DescribeActivityExecution and GetActivityExecutionResult with a single + flexible endpoint that can handle both synchronous queries and long polling for both + info updates and completion. + operationId: GetActivityExecutionStatus parameters: - name: namespace in: path @@ -846,20 +851,19 @@ paths: type: string - name: runId in: query - description: Activity run ID, targets the latest run if run_id is empty. schema: type: string - - name: includeInput + - name: includeInfo.includeInput in: query - description: If true, the activity input is returned in the response. schema: type: boolean - - name: longPollToken + - name: waitAnyStateChange.longPollToken + in: query + schema: + type: string + format: bytes + - name: waitCompletion.longPollToken in: query - description: |- - If not empty, turns this request into a long poll that is unblocked when the activity state changes from the time - the token was returned. - This token is returned as part of the `DescribeActivityExecutionResponse`. schema: type: string format: bytes @@ -869,7 +873,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/DescribeActivityExecutionResponse' + $ref: '#/components/schemas/GetActivityExecutionStatusResponse' default: description: Default error response content: @@ -919,7 +923,16 @@ paths: post: tags: - WorkflowService - description: "RequestCancelActivityExecution requests cancellation of an activity execution.\n\n Requesting to cancel an activity does not automatically transition the activity to canceled status. If the\n activity has a currently running attempt, the activity will only transition to canceled status if the current\n attempt is unsuccessful.\n TODO: Clarify what happens if there are no more allowed retries after the current attempt.\n \n It returns success if the requested activity is already closed.\n TODO: This ^^ is copied from RequestCancelWorkflowExecution, do we want to preserve this behavior?" + description: |- + RequestCancelActivityExecution requests cancellation of an activity execution. + + Requesting to cancel an activity does not automatically transition the activity to canceled status. If the + activity has a currently running attempt, the activity will only transition to canceled status if the current + attempt is unsuccessful. + TODO: Clarify what happens if there are no more allowed retries after the current attempt. + + It returns success if the requested activity is already closed. + TODO: This ^^ is copied from RequestCancelWorkflowExecution, do we want to preserve this behavior? operationId: RequestCancelActivityExecution parameters: - name: namespace @@ -951,51 +964,6 @@ paths: application/json: schema: $ref: '#/components/schemas/Status' - /api/v1/namespaces/{namespace}/activities/{activityId}/result: - get: - tags: - - WorkflowService - description: |- - GetActivityExecutionResult returns the activity result if it is in a terminal status or (optionally) wait for it - to reach one. - operationId: GetActivityExecutionResult - parameters: - - name: namespace - in: path - required: true - schema: - type: string - - name: activityId - in: path - required: true - schema: - type: string - - name: runId - in: query - description: Activity run ID, targets the latest run if run_id is empty. - schema: - type: string - - name: wait - in: query - description: |- - If set, turns this request into a long poll that is unblocked when the activity reaches a terminal status. - The wait duration is capped by the request's context deadline or by the maximum enforced long poll interval - allowed by the server. - schema: - type: boolean - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/GetActivityExecutionResultResponse' - default: - description: Default error response - content: - application/json: - schema: - $ref: '#/components/schemas/Status' /api/v1/namespaces/{namespace}/activities/{activityId}/terminate: post: tags: @@ -5023,12 +4991,17 @@ paths: tags: - WorkflowService description: |- - DescribeActivityExecution returns information about the specified activity execution. - Pass in a long_poll_token to turn this request into a long poll that gets unblocked when the activity makes - progress. - In case the activity has not made progress by the time the long poll request times out, an empty response is - returned and the caller may issue an identical DescribeActivityExecution request to continue polling. - operationId: DescribeActivityExecution + GetActivityExecutionStatus returns the status and/or outcome of an activity execution. + This unified endpoint can: + - Get current activity info synchronously (when include_info is true) + - Long poll for activity info updates (when wait_info is true) + - Get activity outcome synchronously if completed (when include_outcome is true) + - Long poll for activity completion (when wait_outcome is true) + + This replaces both DescribeActivityExecution and GetActivityExecutionResult with a single + flexible endpoint that can handle both synchronous queries and long polling for both + info updates and completion. + operationId: GetActivityExecutionStatus parameters: - name: namespace in: path @@ -5042,20 +5015,19 @@ paths: type: string - name: runId in: query - description: Activity run ID, targets the latest run if run_id is empty. schema: type: string - - name: includeInput + - name: includeInfo.includeInput in: query - description: If true, the activity input is returned in the response. schema: type: boolean - - name: longPollToken + - name: waitAnyStateChange.longPollToken + in: query + schema: + type: string + format: bytes + - name: waitCompletion.longPollToken in: query - description: |- - If not empty, turns this request into a long poll that is unblocked when the activity state changes from the time - the token was returned. - This token is returned as part of the `DescribeActivityExecutionResponse`. schema: type: string format: bytes @@ -5065,7 +5037,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/DescribeActivityExecutionResponse' + $ref: '#/components/schemas/GetActivityExecutionStatusResponse' default: description: Default error response content: @@ -5115,7 +5087,16 @@ paths: post: tags: - WorkflowService - description: "RequestCancelActivityExecution requests cancellation of an activity execution.\n\n Requesting to cancel an activity does not automatically transition the activity to canceled status. If the\n activity has a currently running attempt, the activity will only transition to canceled status if the current\n attempt is unsuccessful.\n TODO: Clarify what happens if there are no more allowed retries after the current attempt.\n \n It returns success if the requested activity is already closed.\n TODO: This ^^ is copied from RequestCancelWorkflowExecution, do we want to preserve this behavior?" + description: |- + RequestCancelActivityExecution requests cancellation of an activity execution. + + Requesting to cancel an activity does not automatically transition the activity to canceled status. If the + activity has a currently running attempt, the activity will only transition to canceled status if the current + attempt is unsuccessful. + TODO: Clarify what happens if there are no more allowed retries after the current attempt. + + It returns success if the requested activity is already closed. + TODO: This ^^ is copied from RequestCancelWorkflowExecution, do we want to preserve this behavior? operationId: RequestCancelActivityExecution parameters: - name: namespace @@ -5147,51 +5128,6 @@ paths: application/json: schema: $ref: '#/components/schemas/Status' - /namespaces/{namespace}/activities/{activityId}/result: - get: - tags: - - WorkflowService - description: |- - GetActivityExecutionResult returns the activity result if it is in a terminal status or (optionally) wait for it - to reach one. - operationId: GetActivityExecutionResult - parameters: - - name: namespace - in: path - required: true - schema: - type: string - - name: activityId - in: path - required: true - schema: - type: string - - name: runId - in: query - description: Activity run ID, targets the latest run if run_id is empty. - schema: - type: string - - name: wait - in: query - description: |- - If set, turns this request into a long poll that is unblocked when the activity reaches a terminal status. - The wait duration is capped by the request's context deadline or by the maximum enforced long poll interval - allowed by the server. - schema: - type: boolean - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/GetActivityExecutionResultResponse' - default: - description: Default error response - content: - application/json: - schema: - $ref: '#/components/schemas/Status' /namespaces/{namespace}/activities/{activityId}/terminate: post: tags: @@ -9507,17 +9443,6 @@ components: Holds information about ongoing transition of a workflow execution from one worker deployment version to another. Experimental. Might change in the future. - DescribeActivityExecutionResponse: - type: object - properties: - info: - $ref: '#/components/schemas/ActivityExecutionInfo' - longPollToken: - type: string - description: |- - A token that can be passed in via a subsequent `DescribeActivityExecutionRequest` to long poll on the activity - state as it makes progress. - format: bytes DescribeBatchOperationResponse: type: object properties: @@ -10052,12 +9977,16 @@ components: allOf: - $ref: '#/components/schemas/WorkerConfig' description: The worker configuration. - GetActivityExecutionResultResponse: + GetActivityExecutionStatusResponse: type: object properties: runId: type: string - description: The run ID of the completed activity, may be used in case a run ID was not specified in the request. + description: The run ID of the activity, useful when run_id was not specified in the request. + info: + allOf: + - $ref: '#/components/schemas/ActivityExecutionInfo' + description: Only set if include_info was present in the request. result: allOf: - $ref: '#/components/schemas/Payloads' @@ -10066,6 +9995,12 @@ components: allOf: - $ref: '#/components/schemas/Failure' description: The failure if the activity completed unsuccessfully. + stateChangeLongPollToken: + type: string + description: |- + Token to use for a follow-on request using wait_any_state_change. + Only set if wait_policy was wait_any_state_change and the activity is not complete. + format: bytes GetClusterInfoResponse: type: object properties: diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index e0a6c68a2..2efd8eff3 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -45,6 +45,7 @@ import "temporal/api/nexus/v1/message.proto"; import "temporal/api/worker/v1/message.proto"; import "google/protobuf/duration.proto"; +import "google/protobuf/empty.proto"; import "google/protobuf/field_mask.proto"; import "google/protobuf/timestamp.proto"; @@ -2667,29 +2668,62 @@ message StartActivityExecutionResponse { temporal.api.common.v1.Link link = 4; } +// Get the status and/or outcome of an activity execution. +// Supported use cases include +// - Get current activity info without waiting +// - Wait for next state change and return activity info +// - Wait for result and return outcome, optionally with info message DescribeActivityExecutionRequest { string namespace = 1; string activity_id = 2; - // Activity run ID, targets the latest run if run_id is empty. string run_id = 3; - // If true, the activity input is returned in the response. - bool include_input = 4; + message IncludeInfoOptions { + bool include_input = 1; + } + IncludeInfoOptions include_info = 4; + + message IncludeOutcomeOptions {} + IncludeOutcomeOptions include_outcome = 5; + + message NoWaitOptions {} + message StateChangeWaitOptions { + bytes long_poll_token = 1; + } + message CompletionWaitOptions {} - // If not empty, turns this request into a long poll that is unblocked when the activity state changes from the time - // the token was returned. - // This token is returned as part of the `DescribeActivityExecutionResponse`. - bytes long_poll_token = 5; + oneof wait_policy { + NoWaitOptions no_wait = 6; + StateChangeWaitOptions wait_any_state_change = 7; + // long_poll_token is currently ignored when waiting for completion + CompletionWaitOptions wait_completion = 8; + } } message DescribeActivityExecutionResponse { - temporal.api.activity.v1.ActivityExecutionInfo info = 1; + // The run ID of the activity, useful when run_id was not specified in the request. + string run_id = 1; + + // Only set if include_info was present in the request. + temporal.api.activity.v1.ActivityExecutionInfo info = 2; - // A token that can be passed in via a subsequent `DescribeActivityExecutionRequest` to long poll on the activity - // state as it makes progress. - bytes long_poll_token = 2; + // Only set if the activity is completed and include_outcome was present in the request. + oneof outcome { + // The result if the activity completed successfully. + temporal.api.common.v1.Payloads result = 3; + // The failure if the activity completed unsuccessfully. + temporal.api.failure.v1.Failure failure = 4; + } + + // Token to use for a follow-on request using wait_any_state_change. + // Only set if wait_policy was wait_any_state_change and the activity is not complete. + bytes state_change_long_poll_token = 5; } + + + + message ListActivityExecutionsRequest { string namespace = 1; // Max number of executions to return per page. @@ -2730,29 +2764,6 @@ message CountActivityExecutionsResponse { } } -message GetActivityExecutionResultRequest { - string namespace = 1; - string activity_id = 2; - // Activity run ID, targets the latest run if run_id is empty. - string run_id = 3; - // If set, turns this request into a long poll that is unblocked when the activity reaches a terminal status. - // The wait duration is capped by the request's context deadline or by the maximum enforced long poll interval - // allowed by the server. - bool wait = 4; -} - -message GetActivityExecutionResultResponse { - // The run ID of the completed activity, may be used in case a run ID was not specified in the request. - string run_id = 1; - - oneof outcome { - // The result if the activity completed successfully. - temporal.api.common.v1.Payloads result = 2; - // The failure if the activity completed unsuccessfully. - temporal.api.failure.v1.Failure failure = 3; - } -} - message RequestCancelActivityExecutionRequest { string namespace = 1; string activity_id = 2; diff --git a/temporal/api/workflowservice/v1/service.proto b/temporal/api/workflowservice/v1/service.proto index 5a7b82387..0dbaf6e8f 100644 --- a/temporal/api/workflowservice/v1/service.proto +++ b/temporal/api/workflowservice/v1/service.proto @@ -1403,11 +1403,16 @@ service WorkflowService { }; } - // DescribeActivityExecution returns information about the specified activity execution. - // Pass in a long_poll_token to turn this request into a long poll that gets unblocked when the activity makes - // progress. - // In case the activity has not made progress by the time the long poll request times out, an empty response is - // returned and the caller may issue an identical DescribeActivityExecution request to continue polling. + // DescribeActivityExecution returns the status and/or outcome of an activity execution. + // This unified endpoint can: + // - Get current activity info synchronously (when include_info is true) + // - Long poll for activity info updates (when wait_info is true) + // - Get activity outcome synchronously if completed (when include_outcome is true) + // - Long poll for activity completion (when wait_outcome is true) + // + // This replaces both DescribeActivityExecution and GetActivityExecutionResult with a single + // flexible endpoint that can handle both synchronous queries and long polling for both + // info updates and completion. rpc DescribeActivityExecution (DescribeActivityExecutionRequest) returns (DescribeActivityExecutionResponse) { option (google.api.http) = { get: "/namespaces/{namespace}/activities/{activity_id}" @@ -1437,24 +1442,13 @@ service WorkflowService { }; } - // GetActivityExecutionResult returns the activity result if it is in a terminal status or (optionally) wait for it - // to reach one. - rpc GetActivityExecutionResult (GetActivityExecutionResultRequest) returns (GetActivityExecutionResultResponse) { - option (google.api.http) = { - get: "/namespaces/{namespace}/activities/{activity_id}/result" - additional_bindings { - get: "/api/v1/namespaces/{namespace}/activities/{activity_id}/result" - } - }; - } - // RequestCancelActivityExecution requests cancellation of an activity execution. // // Requesting to cancel an activity does not automatically transition the activity to canceled status. If the // activity has a currently running attempt, the activity will only transition to canceled status if the current // attempt is unsuccessful. // TODO: Clarify what happens if there are no more allowed retries after the current attempt. - // + // // It returns success if the requested activity is already closed. // TODO: This ^^ is copied from RequestCancelWorkflowExecution, do we want to preserve this behavior? rpc RequestCancelActivityExecution (RequestCancelActivityExecutionRequest) returns (RequestCancelActivityExecutionResponse) { From 14d98bf4bc3162497d2acf92623edf52c433c9c3 Mon Sep 17 00:00:00 2001 From: Dan Davison Date: Wed, 22 Oct 2025 14:20:20 -0400 Subject: [PATCH 2/4] Flatten API --- openapi/openapiv2.json | 133 +++++++++--------- openapi/openapiv3.yaml | 94 +++++++------ temporal/api/activity/v1/message.proto | 21 ++- .../workflowservice/v1/request_response.proto | 33 ++--- 4 files changed, 139 insertions(+), 142 deletions(-) diff --git a/openapi/openapiv2.json b/openapi/openapiv2.json index c38495d95..fe41bcbd3 100644 --- a/openapi/openapiv2.json +++ b/openapi/openapiv2.json @@ -859,14 +859,14 @@ }, "/api/v1/namespaces/{namespace}/activities/{activityId}": { "get": { - "summary": "GetActivityExecutionStatus returns the status and/or outcome of an activity execution.\nThis unified endpoint can:\n- Get current activity info synchronously (when include_info is true)\n- Long poll for activity info updates (when wait_info is true)\n- Get activity outcome synchronously if completed (when include_outcome is true)\n- Long poll for activity completion (when wait_outcome is true)", + "summary": "DescribeActivityExecution returns the status and/or outcome of an activity execution.\nThis unified endpoint can:\n- Get current activity info synchronously (when include_info is true)\n- Long poll for activity info updates (when wait_info is true)\n- Get activity outcome synchronously if completed (when include_outcome is true)\n- Long poll for activity completion (when wait_outcome is true)", "description": "This replaces both DescribeActivityExecution and GetActivityExecutionResult with a single\nflexible endpoint that can handle both synchronous queries and long polling for both\ninfo updates and completion.", - "operationId": "GetActivityExecutionStatus2", + "operationId": "DescribeActivityExecution2", "responses": { "200": { "description": "A successful response.", "schema": { - "$ref": "#/definitions/v1GetActivityExecutionStatusResponse" + "$ref": "#/definitions/v1DescribeActivityExecutionResponse" } }, "default": { @@ -896,26 +896,25 @@ "type": "string" }, { - "name": "includeInfo.includeInput", + "name": "includeInfo", "in": "query", "required": false, "type": "boolean" }, { - "name": "noWait", + "name": "includeInput", "in": "query", "required": false, - "type": "object" + "type": "boolean" }, { - "name": "waitAnyStateChange.longPollToken", + "name": "includeOutcome", "in": "query", "required": false, - "type": "string", - "format": "byte" + "type": "boolean" }, { - "name": "waitCompletion.longPollToken", + "name": "waitAnyStateChange.longPollToken", "in": "query", "required": false, "type": "string", @@ -5434,14 +5433,14 @@ }, "/namespaces/{namespace}/activities/{activityId}": { "get": { - "summary": "GetActivityExecutionStatus returns the status and/or outcome of an activity execution.\nThis unified endpoint can:\n- Get current activity info synchronously (when include_info is true)\n- Long poll for activity info updates (when wait_info is true)\n- Get activity outcome synchronously if completed (when include_outcome is true)\n- Long poll for activity completion (when wait_outcome is true)", + "summary": "DescribeActivityExecution returns the status and/or outcome of an activity execution.\nThis unified endpoint can:\n- Get current activity info synchronously (when include_info is true)\n- Long poll for activity info updates (when wait_info is true)\n- Get activity outcome synchronously if completed (when include_outcome is true)\n- Long poll for activity completion (when wait_outcome is true)", "description": "This replaces both DescribeActivityExecution and GetActivityExecutionResult with a single\nflexible endpoint that can handle both synchronous queries and long polling for both\ninfo updates and completion.", - "operationId": "GetActivityExecutionStatus", + "operationId": "DescribeActivityExecution", "responses": { "200": { "description": "A successful response.", "schema": { - "$ref": "#/definitions/v1GetActivityExecutionStatusResponse" + "$ref": "#/definitions/v1DescribeActivityExecutionResponse" } }, "default": { @@ -5471,26 +5470,25 @@ "type": "string" }, { - "name": "includeInfo.includeInput", + "name": "includeInfo", "in": "query", "required": false, "type": "boolean" }, { - "name": "noWait", + "name": "includeInput", "in": "query", "required": false, - "type": "object" + "type": "boolean" }, { - "name": "waitAnyStateChange.longPollToken", + "name": "includeOutcome", "in": "query", "required": false, - "type": "string", - "format": "byte" + "type": "boolean" }, { - "name": "waitCompletion.longPollToken", + "name": "waitAnyStateChange.longPollToken", "in": "query", "required": false, "type": "string", @@ -8710,6 +8708,21 @@ } } }, + "DescribeActivityExecutionRequestCompletionWaitOptions": { + "type": "object" + }, + "DescribeActivityExecutionRequestNoWaitOptions": { + "type": "object" + }, + "DescribeActivityExecutionRequestStateChangeWaitOptions": { + "type": "object", + "properties": { + "longPollToken": { + "type": "string", + "format": "byte" + } + } + }, "DescribeTaskQueueResponseEffectiveRateLimit": { "type": "object", "properties": { @@ -8783,26 +8796,6 @@ } } }, - "GetActivityExecutionStatusRequestIncludeInfoOptions": { - "type": "object", - "properties": { - "includeInput": { - "type": "boolean" - } - } - }, - "GetActivityExecutionStatusRequestIncludeOutcomeOptions": { - "type": "object" - }, - "GetActivityExecutionStatusRequestWaitOptions": { - "type": "object", - "properties": { - "longPollToken": { - "type": "string", - "format": "byte" - } - } - }, "LinkActivity": { "type": "object", "properties": { @@ -11082,10 +11075,6 @@ "$ref": "#/definitions/v1ActivityOptions", "description": "Current activity options. May be different from the one used to start the activity." }, - "input": { - "$ref": "#/definitions/v1Payloads", - "description": "Serialized activity input, passed as arguments to the activity function." - }, "stateTransitionCount": { "type": "string", "format": "int64", @@ -12798,6 +12787,36 @@ "type": "object", "description": "Deprecated." }, + "v1DescribeActivityExecutionResponse": { + "type": "object", + "properties": { + "runId": { + "type": "string", + "description": "The run ID of the activity, useful when run_id was not specified in the request." + }, + "info": { + "$ref": "#/definitions/v1ActivityExecutionInfo", + "description": "Only set if include_info was present in the request." + }, + "input": { + "$ref": "#/definitions/v1Payloads", + "description": "Serialized activity input, passed as arguments to the activity function." + }, + "result": { + "$ref": "#/definitions/v1Payloads", + "description": "The result if the activity completed successfully." + }, + "failure": { + "$ref": "#/definitions/apifailurev1Failure", + "description": "The failure if the activity completed unsuccessfully." + }, + "stateChangeLongPollToken": { + "type": "string", + "format": "byte", + "description": "Token to use for a follow-on request using wait_any_state_change.\nOnly set if wait_policy was wait_any_state_change and the activity is not complete." + } + } + }, "v1DescribeBatchOperationResponse": { "type": "object", "properties": { @@ -13294,32 +13313,6 @@ } } }, - "v1GetActivityExecutionStatusResponse": { - "type": "object", - "properties": { - "runId": { - "type": "string", - "description": "The run ID of the activity, useful when run_id was not specified in the request." - }, - "info": { - "$ref": "#/definitions/v1ActivityExecutionInfo", - "description": "Only set if include_info was present in the request." - }, - "result": { - "$ref": "#/definitions/v1Payloads", - "description": "The result if the activity completed successfully." - }, - "failure": { - "$ref": "#/definitions/apifailurev1Failure", - "description": "The failure if the activity completed unsuccessfully." - }, - "stateChangeLongPollToken": { - "type": "string", - "format": "byte", - "description": "Token to use for a follow-on request using wait_any_state_change.\nOnly set if wait_policy was wait_any_state_change and the activity is not complete." - } - } - }, "v1GetClusterInfoResponse": { "type": "object", "properties": { diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index 071ae6bdf..ca0c429d7 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -827,7 +827,7 @@ paths: tags: - WorkflowService description: |- - GetActivityExecutionStatus returns the status and/or outcome of an activity execution. + DescribeActivityExecution returns the status and/or outcome of an activity execution. This unified endpoint can: - Get current activity info synchronously (when include_info is true) - Long poll for activity info updates (when wait_info is true) @@ -837,7 +837,7 @@ paths: This replaces both DescribeActivityExecution and GetActivityExecutionResult with a single flexible endpoint that can handle both synchronous queries and long polling for both info updates and completion. - operationId: GetActivityExecutionStatus + operationId: DescribeActivityExecution parameters: - name: namespace in: path @@ -853,16 +853,19 @@ paths: in: query schema: type: string - - name: includeInfo.includeInput + - name: includeInfo in: query schema: type: boolean - - name: waitAnyStateChange.longPollToken + - name: includeInput in: query schema: - type: string - format: bytes - - name: waitCompletion.longPollToken + type: boolean + - name: includeOutcome + in: query + schema: + type: boolean + - name: waitAnyStateChange.longPollToken in: query schema: type: string @@ -873,7 +876,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/GetActivityExecutionStatusResponse' + $ref: '#/components/schemas/DescribeActivityExecutionResponse' default: description: Default error response content: @@ -4991,7 +4994,7 @@ paths: tags: - WorkflowService description: |- - GetActivityExecutionStatus returns the status and/or outcome of an activity execution. + DescribeActivityExecution returns the status and/or outcome of an activity execution. This unified endpoint can: - Get current activity info synchronously (when include_info is true) - Long poll for activity info updates (when wait_info is true) @@ -5001,7 +5004,7 @@ paths: This replaces both DescribeActivityExecution and GetActivityExecutionResult with a single flexible endpoint that can handle both synchronous queries and long polling for both info updates and completion. - operationId: GetActivityExecutionStatus + operationId: DescribeActivityExecution parameters: - name: namespace in: path @@ -5017,16 +5020,19 @@ paths: in: query schema: type: string - - name: includeInfo.includeInput + - name: includeInfo in: query schema: type: boolean - - name: waitAnyStateChange.longPollToken + - name: includeInput in: query schema: - type: string - format: bytes - - name: waitCompletion.longPollToken + type: boolean + - name: includeOutcome + in: query + schema: + type: boolean + - name: waitAnyStateChange.longPollToken in: query schema: type: string @@ -5037,7 +5043,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/GetActivityExecutionStatusResponse' + $ref: '#/components/schemas/DescribeActivityExecutionResponse' default: description: Default error response content: @@ -7993,10 +7999,6 @@ components: allOf: - $ref: '#/components/schemas/ActivityOptions' description: Current activity options. May be different from the one used to start the activity. - input: - allOf: - - $ref: '#/components/schemas/Payloads' - description: Serialized activity input, passed as arguments to the activity function. stateTransitionCount: type: string description: Incremented each time the activity's state is mutated in persistence. @@ -9443,6 +9445,34 @@ components: Holds information about ongoing transition of a workflow execution from one worker deployment version to another. Experimental. Might change in the future. + DescribeActivityExecutionResponse: + type: object + properties: + runId: + type: string + description: The run ID of the activity, useful when run_id was not specified in the request. + info: + allOf: + - $ref: '#/components/schemas/ActivityExecutionInfo' + description: Only set if include_info was present in the request. + input: + allOf: + - $ref: '#/components/schemas/Payloads' + description: Serialized activity input, passed as arguments to the activity function. + result: + allOf: + - $ref: '#/components/schemas/Payloads' + description: The result if the activity completed successfully. + failure: + allOf: + - $ref: '#/components/schemas/Failure' + description: The failure if the activity completed unsuccessfully. + stateChangeLongPollToken: + type: string + description: |- + Token to use for a follow-on request using wait_any_state_change. + Only set if wait_policy was wait_any_state_change and the activity is not complete. + format: bytes DescribeBatchOperationResponse: type: object properties: @@ -9977,30 +10007,6 @@ components: allOf: - $ref: '#/components/schemas/WorkerConfig' description: The worker configuration. - GetActivityExecutionStatusResponse: - type: object - properties: - runId: - type: string - description: The run ID of the activity, useful when run_id was not specified in the request. - info: - allOf: - - $ref: '#/components/schemas/ActivityExecutionInfo' - description: Only set if include_info was present in the request. - result: - allOf: - - $ref: '#/components/schemas/Payloads' - description: The result if the activity completed successfully. - failure: - allOf: - - $ref: '#/components/schemas/Failure' - description: The failure if the activity completed unsuccessfully. - stateChangeLongPollToken: - type: string - description: |- - Token to use for a follow-on request using wait_any_state_change. - Only set if wait_policy was wait_any_state_change and the activity is not complete. - format: bytes GetClusterInfoResponse: type: object properties: diff --git a/temporal/api/activity/v1/message.proto b/temporal/api/activity/v1/message.proto index f658863e5..65be59209 100644 --- a/temporal/api/activity/v1/message.proto +++ b/temporal/api/activity/v1/message.proto @@ -117,28 +117,25 @@ message ActivityExecutionInfo { // Current activity options. May be different from the one used to start the activity. temporal.api.activity.v1.ActivityOptions activity_options = 20; - // Serialized activity input, passed as arguments to the activity function. - temporal.api.common.v1.Payloads input = 21; - // Incremented each time the activity's state is mutated in persistence. - int64 state_transition_count = 22; + int64 state_transition_count = 21; - temporal.api.common.v1.SearchAttributes search_attributes = 23; - temporal.api.common.v1.Header header = 24; + temporal.api.common.v1.SearchAttributes search_attributes = 22; + temporal.api.common.v1.Header header = 23; // Whether the activity was started with a request_eager_execution flag set to `true`, indicating that the first // task was delivered inline in the start response, bypassing matching. - bool eager_execution_requested = 25; + bool eager_execution_requested = 24; // Callbacks to be called by the server when this activity reaches a terminal status. // Callback addresses must be whitelisted in the server's dynamic configuration. - repeated temporal.api.common.v1.Callback completion_callbacks = 26; + repeated temporal.api.common.v1.Callback completion_callbacks = 25; // Metadata for use by user interfaces to display the fixed as-of-start summary and details of the activity. - temporal.api.sdk.v1.UserMetadata user_metadata = 27; + temporal.api.sdk.v1.UserMetadata user_metadata = 26; // Links to be associated with the activity. - repeated temporal.api.common.v1.Link links = 28; + repeated temporal.api.common.v1.Link links = 27; // Set if activity cancelation was requested. - string canceled_reason = 29; + string canceled_reason = 28; // TODO: Move this to a common package? message PauseInfo { @@ -158,7 +155,7 @@ message ActivityExecutionInfo { } } - PauseInfo pause_info = 30; + PauseInfo pause_info = 29; } // Limited activity information returned in the list response. diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index 2efd8eff3..44b2b2038 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -45,7 +45,6 @@ import "temporal/api/nexus/v1/message.proto"; import "temporal/api/worker/v1/message.proto"; import "google/protobuf/duration.proto"; -import "google/protobuf/empty.proto"; import "google/protobuf/field_mask.proto"; import "google/protobuf/timestamp.proto"; @@ -2678,13 +2677,9 @@ message DescribeActivityExecutionRequest { string activity_id = 2; string run_id = 3; - message IncludeInfoOptions { - bool include_input = 1; - } - IncludeInfoOptions include_info = 4; - - message IncludeOutcomeOptions {} - IncludeOutcomeOptions include_outcome = 5; + bool include_info = 4; + bool include_input = 5; + bool include_outcome = 6; message NoWaitOptions {} message StateChangeWaitOptions { @@ -2693,10 +2688,13 @@ message DescribeActivityExecutionRequest { message CompletionWaitOptions {} oneof wait_policy { - NoWaitOptions no_wait = 6; - StateChangeWaitOptions wait_any_state_change = 7; + NoWaitOptions no_wait = 7; + // The state may change multiple times between requests and the API returns the current + // state. Therefore it is not guaranteed that a client making a sequence of long-poll + // requests will see a complete sequence of state changes. + StateChangeWaitOptions wait_any_state_change = 8; // long_poll_token is currently ignored when waiting for completion - CompletionWaitOptions wait_completion = 8; + CompletionWaitOptions wait_completion = 9; } } @@ -2704,20 +2702,23 @@ message DescribeActivityExecutionResponse { // The run ID of the activity, useful when run_id was not specified in the request. string run_id = 1; - // Only set if include_info was present in the request. + // Only set if include_info was true in the request. temporal.api.activity.v1.ActivityExecutionInfo info = 2; - // Only set if the activity is completed and include_outcome was present in the request. + // Serialized activity input, passed as arguments to the activity function. + temporal.api.common.v1.Payloads input = 3; + + // Only set if the activity is completed and include_outcome was true in the request. oneof outcome { // The result if the activity completed successfully. - temporal.api.common.v1.Payloads result = 3; + temporal.api.common.v1.Payloads result = 4; // The failure if the activity completed unsuccessfully. - temporal.api.failure.v1.Failure failure = 4; + temporal.api.failure.v1.Failure failure = 5; } // Token to use for a follow-on request using wait_any_state_change. // Only set if wait_policy was wait_any_state_change and the activity is not complete. - bytes state_change_long_poll_token = 5; + bytes state_change_long_poll_token = 6; } From 7b147cb4edc12afc792f34a09fdf654047372ef3 Mon Sep 17 00:00:00 2001 From: Dan Davison Date: Wed, 22 Oct 2025 15:06:10 -0400 Subject: [PATCH 3/4] Include info by default --- openapi/openapiv2.json | 6 +++--- openapi/openapiv3.yaml | 6 +++--- temporal/api/workflowservice/v1/request_response.proto | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/openapi/openapiv2.json b/openapi/openapiv2.json index fe41bcbd3..e0e9f81fd 100644 --- a/openapi/openapiv2.json +++ b/openapi/openapiv2.json @@ -896,7 +896,7 @@ "type": "string" }, { - "name": "includeInfo", + "name": "excludeInfo", "in": "query", "required": false, "type": "boolean" @@ -5470,7 +5470,7 @@ "type": "string" }, { - "name": "includeInfo", + "name": "excludeInfo", "in": "query", "required": false, "type": "boolean" @@ -12796,7 +12796,7 @@ }, "info": { "$ref": "#/definitions/v1ActivityExecutionInfo", - "description": "Only set if include_info was present in the request." + "description": "Only set if include_info was true in the request." }, "input": { "$ref": "#/definitions/v1Payloads", diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index ca0c429d7..e3175359e 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -853,7 +853,7 @@ paths: in: query schema: type: string - - name: includeInfo + - name: excludeInfo in: query schema: type: boolean @@ -5020,7 +5020,7 @@ paths: in: query schema: type: string - - name: includeInfo + - name: excludeInfo in: query schema: type: boolean @@ -9454,7 +9454,7 @@ components: info: allOf: - $ref: '#/components/schemas/ActivityExecutionInfo' - description: Only set if include_info was present in the request. + description: Only set if include_info was true in the request. input: allOf: - $ref: '#/components/schemas/Payloads' diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index 44b2b2038..b84fccf57 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -2677,7 +2677,7 @@ message DescribeActivityExecutionRequest { string activity_id = 2; string run_id = 3; - bool include_info = 4; + bool exclude_info = 4; bool include_input = 5; bool include_outcome = 6; From 05568fe61aa970ce2e4b5f4204f79e8bc3a7a15e Mon Sep 17 00:00:00 2001 From: Dan Davison Date: Wed, 22 Oct 2025 15:14:59 -0400 Subject: [PATCH 4/4] Updates from code review --- openapi/openapiv2.json | 19 +++++++--- openapi/openapiv3.yaml | 36 +++++++++---------- .../workflowservice/v1/request_response.proto | 11 +++--- temporal/api/workflowservice/v1/service.proto | 13 +++---- 4 files changed, 41 insertions(+), 38 deletions(-) diff --git a/openapi/openapiv2.json b/openapi/openapiv2.json index e0e9f81fd..cb9acb69c 100644 --- a/openapi/openapiv2.json +++ b/openapi/openapiv2.json @@ -859,8 +859,7 @@ }, "/api/v1/namespaces/{namespace}/activities/{activityId}": { "get": { - "summary": "DescribeActivityExecution returns the status and/or outcome of an activity execution.\nThis unified endpoint can:\n- Get current activity info synchronously (when include_info is true)\n- Long poll for activity info updates (when wait_info is true)\n- Get activity outcome synchronously if completed (when include_outcome is true)\n- Long poll for activity completion (when wait_outcome is true)", - "description": "This replaces both DescribeActivityExecution and GetActivityExecutionResult with a single\nflexible endpoint that can handle both synchronous queries and long polling for both\ninfo updates and completion.", + "summary": "DescribeActivityExecution returns the status and/or outcome of an activity execution.\nSupported use cases include\n- Get current activity info without waiting\n- Wait for next state change and return activity info\n- Wait for completion and return outcome", "operationId": "DescribeActivityExecution2", "responses": { "200": { @@ -891,30 +890,35 @@ }, { "name": "runId", + "description": "Activity run ID. If empty the request targets the latest run.", "in": "query", "required": false, "type": "string" }, { "name": "excludeInfo", + "description": "Exclude the info field from the response.", "in": "query", "required": false, "type": "boolean" }, { "name": "includeInput", + "description": "Include the input field in the response.", "in": "query", "required": false, "type": "boolean" }, { "name": "includeOutcome", + "description": "Include the outcome field in the response.", "in": "query", "required": false, "type": "boolean" }, { "name": "waitAnyStateChange.longPollToken", + "description": "If present, run_id must also be present.", "in": "query", "required": false, "type": "string", @@ -5433,8 +5437,7 @@ }, "/namespaces/{namespace}/activities/{activityId}": { "get": { - "summary": "DescribeActivityExecution returns the status and/or outcome of an activity execution.\nThis unified endpoint can:\n- Get current activity info synchronously (when include_info is true)\n- Long poll for activity info updates (when wait_info is true)\n- Get activity outcome synchronously if completed (when include_outcome is true)\n- Long poll for activity completion (when wait_outcome is true)", - "description": "This replaces both DescribeActivityExecution and GetActivityExecutionResult with a single\nflexible endpoint that can handle both synchronous queries and long polling for both\ninfo updates and completion.", + "summary": "DescribeActivityExecution returns the status and/or outcome of an activity execution.\nSupported use cases include\n- Get current activity info without waiting\n- Wait for next state change and return activity info\n- Wait for completion and return outcome", "operationId": "DescribeActivityExecution", "responses": { "200": { @@ -5465,30 +5468,35 @@ }, { "name": "runId", + "description": "Activity run ID. If empty the request targets the latest run.", "in": "query", "required": false, "type": "string" }, { "name": "excludeInfo", + "description": "Exclude the info field from the response.", "in": "query", "required": false, "type": "boolean" }, { "name": "includeInput", + "description": "Include the input field in the response.", "in": "query", "required": false, "type": "boolean" }, { "name": "includeOutcome", + "description": "Include the outcome field in the response.", "in": "query", "required": false, "type": "boolean" }, { "name": "waitAnyStateChange.longPollToken", + "description": "If present, run_id must also be present.", "in": "query", "required": false, "type": "string", @@ -8719,7 +8727,8 @@ "properties": { "longPollToken": { "type": "string", - "format": "byte" + "format": "byte", + "description": "If present, run_id must also be present." } } }, diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index e3175359e..eda0b74ef 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -828,15 +828,10 @@ paths: - WorkflowService description: |- DescribeActivityExecution returns the status and/or outcome of an activity execution. - This unified endpoint can: - - Get current activity info synchronously (when include_info is true) - - Long poll for activity info updates (when wait_info is true) - - Get activity outcome synchronously if completed (when include_outcome is true) - - Long poll for activity completion (when wait_outcome is true) - - This replaces both DescribeActivityExecution and GetActivityExecutionResult with a single - flexible endpoint that can handle both synchronous queries and long polling for both - info updates and completion. + Supported use cases include + - Get current activity info without waiting + - Wait for next state change and return activity info + - Wait for completion and return outcome operationId: DescribeActivityExecution parameters: - name: namespace @@ -851,22 +846,27 @@ paths: type: string - name: runId in: query + description: Activity run ID. If empty the request targets the latest run. schema: type: string - name: excludeInfo in: query + description: Exclude the info field from the response. schema: type: boolean - name: includeInput in: query + description: Include the input field in the response. schema: type: boolean - name: includeOutcome in: query + description: Include the outcome field in the response. schema: type: boolean - name: waitAnyStateChange.longPollToken in: query + description: If present, run_id must also be present. schema: type: string format: bytes @@ -4995,15 +4995,10 @@ paths: - WorkflowService description: |- DescribeActivityExecution returns the status and/or outcome of an activity execution. - This unified endpoint can: - - Get current activity info synchronously (when include_info is true) - - Long poll for activity info updates (when wait_info is true) - - Get activity outcome synchronously if completed (when include_outcome is true) - - Long poll for activity completion (when wait_outcome is true) - - This replaces both DescribeActivityExecution and GetActivityExecutionResult with a single - flexible endpoint that can handle both synchronous queries and long polling for both - info updates and completion. + Supported use cases include + - Get current activity info without waiting + - Wait for next state change and return activity info + - Wait for completion and return outcome operationId: DescribeActivityExecution parameters: - name: namespace @@ -5018,22 +5013,27 @@ paths: type: string - name: runId in: query + description: Activity run ID. If empty the request targets the latest run. schema: type: string - name: excludeInfo in: query + description: Exclude the info field from the response. schema: type: boolean - name: includeInput in: query + description: Include the input field in the response. schema: type: boolean - name: includeOutcome in: query + description: Include the outcome field in the response. schema: type: boolean - name: waitAnyStateChange.longPollToken in: query + description: If present, run_id must also be present. schema: type: string format: bytes diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index b84fccf57..05f7e39b0 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -2667,22 +2667,21 @@ message StartActivityExecutionResponse { temporal.api.common.v1.Link link = 4; } -// Get the status and/or outcome of an activity execution. -// Supported use cases include -// - Get current activity info without waiting -// - Wait for next state change and return activity info -// - Wait for result and return outcome, optionally with info message DescribeActivityExecutionRequest { string namespace = 1; string activity_id = 2; + // Activity run ID. If empty the request targets the latest run. string run_id = 3; - + // Exclude the info field from the response. bool exclude_info = 4; + // Include the input field in the response. bool include_input = 5; + // Include the outcome field in the response. bool include_outcome = 6; message NoWaitOptions {} message StateChangeWaitOptions { + // If present, run_id must also be present. bytes long_poll_token = 1; } message CompletionWaitOptions {} diff --git a/temporal/api/workflowservice/v1/service.proto b/temporal/api/workflowservice/v1/service.proto index 0dbaf6e8f..7c6dac980 100644 --- a/temporal/api/workflowservice/v1/service.proto +++ b/temporal/api/workflowservice/v1/service.proto @@ -1404,15 +1404,10 @@ service WorkflowService { } // DescribeActivityExecution returns the status and/or outcome of an activity execution. - // This unified endpoint can: - // - Get current activity info synchronously (when include_info is true) - // - Long poll for activity info updates (when wait_info is true) - // - Get activity outcome synchronously if completed (when include_outcome is true) - // - Long poll for activity completion (when wait_outcome is true) - // - // This replaces both DescribeActivityExecution and GetActivityExecutionResult with a single - // flexible endpoint that can handle both synchronous queries and long polling for both - // info updates and completion. + // Supported use cases include + // - Get current activity info without waiting + // - Wait for next state change and return activity info + // - Wait for completion and return outcome rpc DescribeActivityExecution (DescribeActivityExecutionRequest) returns (DescribeActivityExecutionResponse) { option (google.api.http) = { get: "/namespaces/{namespace}/activities/{activity_id}"