From 94d5e407606da0f201105406986a45bf1d583653 Mon Sep 17 00:00:00 2001 From: sam Date: Thu, 28 May 2026 09:24:32 -0700 Subject: [PATCH 1/2] Adds state_size_bytes to operation execution info --- openapi/openapiv2.json | 10 + openapi/openapiv3.yaml | 6 + temporal/api/nexus/v1/message.proto | 575 ++++++++++++++-------------- 3 files changed, 306 insertions(+), 285 deletions(-) diff --git a/openapi/openapiv2.json b/openapi/openapiv2.json index 61d98c55a..2e047a214 100644 --- a/openapi/openapiv2.json +++ b/openapi/openapiv2.json @@ -16985,6 +16985,11 @@ "identity": { "type": "string", "description": "The identity of the client who started this operation." + }, + "stateSizeBytes": { + "type": "string", + "format": "int64", + "description": "Updated once on scheduled and once on terminal status." } }, "description": "Full current state of a standalone Nexus operation, as of the time of the request." @@ -17038,6 +17043,11 @@ "executionDuration": { "type": "string", "description": "The difference between close time and scheduled time.\nThis field is only populated if the operation is closed." + }, + "stateSizeBytes": { + "type": "string", + "format": "int64", + "description": "Updated once on scheduled and once on terminal status." } }, "description": "Limited Nexus operation information returned in the list response.\nWhen adding fields here, ensure that it is also present in NexusOperationExecutionInfo (note that it may already be present in\nNexusOperationExecutionInfo but not at the top-level)." diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index f7053f93a..bc79eb4fc 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -13371,6 +13371,9 @@ components: identity: type: string description: The identity of the client who started this operation. + stateSizeBytes: + type: string + description: Updated once on scheduled and once on terminal status. description: Full current state of a standalone Nexus operation, as of the time of the request. NexusOperationExecutionListInfo: type: object @@ -13423,6 +13426,9 @@ components: description: |- The difference between close time and scheduled time. This field is only populated if the operation is closed. + stateSizeBytes: + type: string + description: Updated once on scheduled and once on terminal status. description: |- Limited Nexus operation information returned in the list response. When adding fields here, ensure that it is also present in NexusOperationExecutionInfo (note that it may already be present in diff --git a/temporal/api/nexus/v1/message.proto b/temporal/api/nexus/v1/message.proto index ec03a2ac7..8133d4dab 100644 --- a/temporal/api/nexus/v1/message.proto +++ b/temporal/api/nexus/v1/message.proto @@ -2,13 +2,6 @@ syntax = "proto3"; package temporal.api.nexus.v1; -option go_package = "go.temporal.io/api/nexus/v1;nexus"; -option java_package = "io.temporal.api.nexus.v1"; -option java_multiple_files = true; -option java_outer_classname = "MessageProto"; -option ruby_package = "Temporalio::Api::Nexus::V1"; -option csharp_namespace = "Temporalio.Api.Nexus.V1"; - import "google/protobuf/duration.proto"; import "google/protobuf/timestamp.proto"; import "temporal/api/common/v1/message.proto"; @@ -17,349 +10,361 @@ import "temporal/api/enums/v1/nexus.proto"; import "temporal/api/failure/v1/message.proto"; import "temporal/api/sdk/v1/user_metadata.proto"; +option csharp_namespace = "Temporalio.Api.Nexus.V1"; +option go_package = "go.temporal.io/api/nexus/v1;nexus"; +option java_multiple_files = true; +option java_outer_classname = "MessageProto"; +option java_package = "io.temporal.api.nexus.v1"; +option ruby_package = "Temporalio::Api::Nexus::V1"; + // A general purpose failure message. // See: https://github.com/nexus-rpc/api/blob/main/SPEC.md#failure message Failure { - string message = 1; - string stack_trace = 4; - map metadata = 2; - // UTF-8 encoded JSON serializable details. - bytes details = 3; - Failure cause = 5; + string message = 1; + string stack_trace = 4; + map metadata = 2; + // UTF-8 encoded JSON serializable details. + bytes details = 3; + Failure cause = 5; } message HandlerError { - // See https://github.com/nexus-rpc/api/blob/main/SPEC.md#predefined-handler-errors. - string error_type = 1; - Failure failure = 2; - // Retry behavior, defaults to the retry behavior of the error type as defined in the spec. - temporal.api.enums.v1.NexusHandlerErrorRetryBehavior retry_behavior = 3; + // See https://github.com/nexus-rpc/api/blob/main/SPEC.md#predefined-handler-errors. + string error_type = 1; + Failure failure = 2; + // Retry behavior, defaults to the retry behavior of the error type as defined in the spec. + temporal.api.enums.v1.NexusHandlerErrorRetryBehavior retry_behavior = 3; } message UnsuccessfulOperationError { - // See https://github.com/nexus-rpc/api/blob/main/SPEC.md#operationinfo. - string operation_state = 1; - Failure failure = 2; + // See https://github.com/nexus-rpc/api/blob/main/SPEC.md#operationinfo. + string operation_state = 1; + Failure failure = 2; } message Link { - // See https://github.com/nexus-rpc/api/blob/main/SPEC.md#links. - string url = 1; - string type = 2; + // See https://github.com/nexus-rpc/api/blob/main/SPEC.md#links. + string url = 1; + string type = 2; } // A request to start an operation. message StartOperationRequest { - // Name of service to start the operation in. - string service = 1; - // Type of operation to start. - string operation = 2; - // A request ID that can be used as an idempotentency key. - string request_id = 3; - // Callback URL to call upon completion if the started operation is async. - string callback = 4; - // Full request body from the incoming HTTP request. - temporal.api.common.v1.Payload payload = 5; - // Header that is expected to be attached to the callback request when the operation completes. - map callback_header = 6; - // Links contain caller information and can be attached to the operations started by the handler. - repeated Link links = 7; + // Name of service to start the operation in. + string service = 1; + // Type of operation to start. + string operation = 2; + // A request ID that can be used as an idempotentency key. + string request_id = 3; + // Callback URL to call upon completion if the started operation is async. + string callback = 4; + // Full request body from the incoming HTTP request. + temporal.api.common.v1.Payload payload = 5; + // Header that is expected to be attached to the callback request when the operation completes. + map callback_header = 6; + // Links contain caller information and can be attached to the operations started by the handler. + repeated Link links = 7; } // A request to cancel an operation. message CancelOperationRequest { - // Service name. - string service = 1; - // Type of operation to cancel. - string operation = 2; - // Operation ID as originally generated by a Handler. - // - // Deprecated. Renamed to operation_token. - string operation_id = 3 [deprecated = true]; - - // Operation token as originally generated by a Handler. - string operation_token = 4; + // Service name. + string service = 1; + // Type of operation to cancel. + string operation = 2; + // Operation ID as originally generated by a Handler. + // + // Deprecated. Renamed to operation_token. + string operation_id = 3 [deprecated = true]; + + // Operation token as originally generated by a Handler. + string operation_token = 4; } // A Nexus request. message Request { - message Capabilities { - // If set, handlers may use temporal.api.failure.v1.Failure instances to return failures to the server. - // This also allows handler and operation errors to have their own messages and stack traces. - bool temporal_failure_responses = 1; - } - - // Headers extracted from the original request in the Temporal frontend. - // When using Nexus over HTTP, this includes the request's HTTP headers ignoring multiple values. - map header = 1; - - // The timestamp when the request was scheduled in the frontend. - // (-- api-linter: core::0142::time-field-names=disabled - // aip.dev/not-precedent: Not following linter rules. --) - google.protobuf.Timestamp scheduled_time = 2; - - Capabilities capabilities = 100; - - oneof variant { - StartOperationRequest start_operation = 3; - CancelOperationRequest cancel_operation = 4; - } - - // The endpoint this request was addressed to before forwarding to the worker. - // Supported from server version 1.30.0. - string endpoint = 10; + message Capabilities { + // If set, handlers may use temporal.api.failure.v1.Failure instances to return failures to the server. + // This also allows handler and operation errors to have their own messages and stack traces. + bool temporal_failure_responses = 1; + } + + // Headers extracted from the original request in the Temporal frontend. + // When using Nexus over HTTP, this includes the request's HTTP headers ignoring multiple values. + map header = 1; + + // The timestamp when the request was scheduled in the frontend. + // (-- api-linter: core::0142::time-field-names=disabled + // aip.dev/not-precedent: Not following linter rules. --) + google.protobuf.Timestamp scheduled_time = 2; + + Capabilities capabilities = 100; + + oneof variant { + StartOperationRequest start_operation = 3; + CancelOperationRequest cancel_operation = 4; + } + + // The endpoint this request was addressed to before forwarding to the worker. + // Supported from server version 1.30.0. + string endpoint = 10; } // Response variant for StartOperationRequest. message StartOperationResponse { - // An operation completed successfully. - message Sync { - temporal.api.common.v1.Payload payload = 1; - repeated Link links = 2; - } - - // The operation will complete asynchronously. - // The returned ID can be used to reference this operation. - message Async { - // Deprecated. Renamed to operation_token. - string operation_id = 1 [deprecated = true]; - repeated Link links = 2; - string operation_token = 3; - } - - oneof variant { - Sync sync_success = 1; - Async async_success = 2; - // The operation completed unsuccessfully (failed or canceled). - // Deprecated. Use the failure variant instead. - UnsuccessfulOperationError operation_error = 3 [deprecated = true]; - // The operation completed unsuccessfully (failed or canceled). - // Failure object must contain an ApplicationFailureInfo or CanceledFailureInfo object. - temporal.api.failure.v1.Failure failure = 4; - } + // An operation completed successfully. + message Sync { + temporal.api.common.v1.Payload payload = 1; + repeated Link links = 2; + } + + // The operation will complete asynchronously. + // The returned ID can be used to reference this operation. + message Async { + // Deprecated. Renamed to operation_token. + string operation_id = 1 [deprecated = true]; + repeated Link links = 2; + string operation_token = 3; + } + + oneof variant { + Sync sync_success = 1; + Async async_success = 2; + // The operation completed unsuccessfully (failed or canceled). + // Deprecated. Use the failure variant instead. + UnsuccessfulOperationError operation_error = 3 [deprecated = true]; + // The operation completed unsuccessfully (failed or canceled). + // Failure object must contain an ApplicationFailureInfo or CanceledFailureInfo object. + temporal.api.failure.v1.Failure failure = 4; + } } // Response variant for CancelOperationRequest. -message CancelOperationResponse { -} +message CancelOperationResponse {} // A response indicating that the handler has successfully processed a request. message Response { - // Variant must correlate to the corresponding Request's variant. - oneof variant { - StartOperationResponse start_operation = 1; - CancelOperationResponse cancel_operation = 2; - } + // Variant must correlate to the corresponding Request's variant. + oneof variant { + StartOperationResponse start_operation = 1; + CancelOperationResponse cancel_operation = 2; + } } // A cluster-global binding from an endpoint ID to a target for dispatching incoming Nexus requests. message Endpoint { - // Data version for this endpoint, incremented for every update issued via the UpdateNexusEndpoint API. - int64 version = 1; - // Unique server-generated endpoint ID. - string id = 2; - // Spec for the endpoint. - EndpointSpec spec = 3; - - // The date and time when the endpoint was created. - // (-- api-linter: core::0142::time-field-names=disabled - // aip.dev/not-precedent: Not following linter rules. --) - google.protobuf.Timestamp created_time = 4; - - // The date and time when the endpoint was last modified. - // Will not be set if the endpoint has never been modified. - // (-- api-linter: core::0142::time-field-names=disabled - // aip.dev/not-precedent: Not following linter rules. --) - google.protobuf.Timestamp last_modified_time = 5; - - // Server exposed URL prefix for invocation of operations on this endpoint. - // This doesn't include the protocol, hostname or port as the server does not know how it should be accessed - // publicly. The URL is stable in the face of endpoint renames. - string url_prefix = 6; + // Data version for this endpoint, incremented for every update issued via the UpdateNexusEndpoint API. + int64 version = 1; + // Unique server-generated endpoint ID. + string id = 2; + // Spec for the endpoint. + EndpointSpec spec = 3; + + // The date and time when the endpoint was created. + // (-- api-linter: core::0142::time-field-names=disabled + // aip.dev/not-precedent: Not following linter rules. --) + google.protobuf.Timestamp created_time = 4; + + // The date and time when the endpoint was last modified. + // Will not be set if the endpoint has never been modified. + // (-- api-linter: core::0142::time-field-names=disabled + // aip.dev/not-precedent: Not following linter rules. --) + google.protobuf.Timestamp last_modified_time = 5; + + // Server exposed URL prefix for invocation of operations on this endpoint. + // This doesn't include the protocol, hostname or port as the server does not know how it should be accessed + // publicly. The URL is stable in the face of endpoint renames. + string url_prefix = 6; } // Contains mutable fields for an Endpoint. message EndpointSpec { - // Endpoint name, unique for this cluster. Must match `[a-zA-Z_][a-zA-Z0-9_]*`. - // Renaming an endpoint breaks all workflow callers that reference this endpoint, causing operations to fail. - string name = 1; + // Endpoint name, unique for this cluster. Must match `[a-zA-Z_][a-zA-Z0-9_]*`. + // Renaming an endpoint breaks all workflow callers that reference this endpoint, causing operations to fail. + string name = 1; - // Markdown description serialized as a single JSON string. - // If the Payload is encrypted, the UI and CLI may decrypt with the configured codec server endpoint. - // By default, the server enforces a limit of 20,000 bytes for this entire payload. - temporal.api.common.v1.Payload description = 2; + // Markdown description serialized as a single JSON string. + // If the Payload is encrypted, the UI and CLI may decrypt with the configured codec server endpoint. + // By default, the server enforces a limit of 20,000 bytes for this entire payload. + temporal.api.common.v1.Payload description = 2; - // Target to route requests to. - EndpointTarget target = 3; + // Target to route requests to. + EndpointTarget target = 3; } // Target to route requests to. message EndpointTarget { - // Target a worker polling on a Nexus task queue in a specific namespace. - message Worker { - // Namespace to route requests to. - string namespace = 1; - // Nexus task queue to route requests to. - string task_queue = 2; - } - - // Target an external server by URL. - // At a later point, this will support providing credentials, in the meantime, an http.RoundTripper can be injected - // into the server to modify the request. - message External { - // URL to call. - string url = 1; - } - - oneof variant { - Worker worker = 1; - External external = 2; - } + // Target a worker polling on a Nexus task queue in a specific namespace. + message Worker { + // Namespace to route requests to. + string namespace = 1; + // Nexus task queue to route requests to. + string task_queue = 2; + } + + // Target an external server by URL. + // At a later point, this will support providing credentials, in the meantime, an http.RoundTripper can be injected + // into the server to modify the request. + message External { + // URL to call. + string url = 1; + } + + oneof variant { + Worker worker = 1; + External external = 2; + } } // NexusOperationExecutionCancellationInfo contains the state of a Nexus operation cancellation. message NexusOperationExecutionCancellationInfo { - // The time when cancellation was requested. - google.protobuf.Timestamp requested_time = 1; + // The time when cancellation was requested. + google.protobuf.Timestamp requested_time = 1; - temporal.api.enums.v1.NexusOperationCancellationState state = 2; + temporal.api.enums.v1.NexusOperationCancellationState state = 2; - // The number of attempts made to deliver the cancel operation request. - // This number represents a minimum bound since the attempt is incremented after the request completes. - int32 attempt = 3; + // The number of attempts made to deliver the cancel operation request. + // This number represents a minimum bound since the attempt is incremented after the request completes. + int32 attempt = 3; - // The time when the last attempt completed. - google.protobuf.Timestamp last_attempt_complete_time = 4; - // The last attempt's failure, if any. - temporal.api.failure.v1.Failure last_attempt_failure = 5; - // The time when the next attempt is scheduled. - google.protobuf.Timestamp next_attempt_schedule_time = 6; + // The time when the last attempt completed. + google.protobuf.Timestamp last_attempt_complete_time = 4; + // The last attempt's failure, if any. + temporal.api.failure.v1.Failure last_attempt_failure = 5; + // The time when the next attempt is scheduled. + google.protobuf.Timestamp next_attempt_schedule_time = 6; - // If the state is BLOCKED, blocked reason provides additional information. - string blocked_reason = 7; + // If the state is BLOCKED, blocked reason provides additional information. + string blocked_reason = 7; - // A reason that may be specified in the CancelNexusOperationRequest. - string reason = 8; + // A reason that may be specified in the CancelNexusOperationRequest. + string reason = 8; } // Full current state of a standalone Nexus operation, as of the time of the request. message NexusOperationExecutionInfo { - // Unique identifier of this Nexus operation within its namespace along with run ID (below). - string operation_id = 1; - string run_id = 2; - - // Endpoint name, resolved to a URL via the cluster's endpoint registry. - string endpoint = 3; - // Service name. - string service = 4; - // Operation name. - string operation = 5; - - // A general status for this operation, indicates whether it is currently running or in one of the terminal statuses. - // Updated once when the operation is originally scheduled, and again when it reaches a terminal status. - temporal.api.enums.v1.NexusOperationExecutionStatus status = 6; - // More detailed breakdown of NEXUS_OPERATION_EXECUTION_STATUS_RUNNING. - temporal.api.enums.v1.PendingNexusOperationState state = 7; - - // Schedule-to-close timeout for this operation. - // (-- api-linter: core::0140::prepositions=disabled - // aip.dev/not-precedent: "to" is used to indicate interval. --) - google.protobuf.Duration schedule_to_close_timeout = 8; - - // Schedule-to-start timeout for this operation. - // (-- api-linter: core::0140::prepositions=disabled - // aip.dev/not-precedent: "to" is used to indicate interval. --) - google.protobuf.Duration schedule_to_start_timeout = 9; - - // Start-to-close timeout for this operation. - // (-- api-linter: core::0140::prepositions=disabled - // aip.dev/not-precedent: "to" is used to indicate interval. --) - google.protobuf.Duration start_to_close_timeout = 10; - - // The number of attempts made to deliver the start operation request. - // This number is approximate, it is incremented when a task is added to the history queue. - // In practice, there could be more attempts if a task is executed but fails to commit, or less attempts if a task - // was never executed. - int32 attempt = 11; - - // Time the operation was originally scheduled via a StartNexusOperation request. - google.protobuf.Timestamp schedule_time = 12; - // Scheduled time + schedule to close timeout. - google.protobuf.Timestamp expiration_time = 13; - // Time when the operation transitioned to a closed state. - google.protobuf.Timestamp close_time = 14; - - // The time when the last attempt completed. - google.protobuf.Timestamp last_attempt_complete_time = 15; - // The last attempt's failure, if any. - temporal.api.failure.v1.Failure last_attempt_failure = 16; - // The time when the next attempt is scheduled. - google.protobuf.Timestamp next_attempt_schedule_time = 17; - - // Elapsed time from schedule_time to now for running operations or to close_time for closed - // operations, including all attempts and backoff between attempts. - google.protobuf.Duration execution_duration = 18; - - NexusOperationExecutionCancellationInfo cancellation_info = 19; - - // If the state is BLOCKED, blocked reason provides additional information. - string blocked_reason = 20; - - // Server-generated request ID used as an idempotency token when submitting start requests to - // the handler. Distinct from the request_id in StartNexusOperationRequest, which is the - // caller-side idempotency key for the StartNexusOperation RPC itself. - string request_id = 21; - - // Operation token. Only set for asynchronous operations after a successful StartOperation call. - string operation_token = 22; - - // Incremented each time the operation's state is mutated in persistence. - int64 state_transition_count = 23; - - temporal.api.common.v1.SearchAttributes search_attributes = 24; - - // Header for context propagation and tracing purposes. - map nexus_header = 25; - - // Metadata for use by user interfaces to display the fixed as-of-start summary and details of the operation. - temporal.api.sdk.v1.UserMetadata user_metadata = 26; - - // Links attached by the handler of this operation on start or completion. - repeated temporal.api.common.v1.Link links = 27; - - // The identity of the client who started this operation. - string identity = 28; + // Unique identifier of this Nexus operation within its namespace along with run ID (below). + string operation_id = 1; + string run_id = 2; + + // Endpoint name, resolved to a URL via the cluster's endpoint registry. + string endpoint = 3; + // Service name. + string service = 4; + // Operation name. + string operation = 5; + + // A general status for this operation, indicates whether it is currently running or in one of the terminal statuses. + // Updated once when the operation is originally scheduled, and again when it reaches a terminal status. + temporal.api.enums.v1.NexusOperationExecutionStatus status = 6; + // More detailed breakdown of NEXUS_OPERATION_EXECUTION_STATUS_RUNNING. + temporal.api.enums.v1.PendingNexusOperationState state = 7; + + // Schedule-to-close timeout for this operation. + // (-- api-linter: core::0140::prepositions=disabled + // aip.dev/not-precedent: "to" is used to indicate interval. --) + google.protobuf.Duration schedule_to_close_timeout = 8; + + // Schedule-to-start timeout for this operation. + // (-- api-linter: core::0140::prepositions=disabled + // aip.dev/not-precedent: "to" is used to indicate interval. --) + google.protobuf.Duration schedule_to_start_timeout = 9; + + // Start-to-close timeout for this operation. + // (-- api-linter: core::0140::prepositions=disabled + // aip.dev/not-precedent: "to" is used to indicate interval. --) + google.protobuf.Duration start_to_close_timeout = 10; + + // The number of attempts made to deliver the start operation request. + // This number is approximate, it is incremented when a task is added to the history queue. + // In practice, there could be more attempts if a task is executed but fails to commit, or less attempts if a task + // was never executed. + int32 attempt = 11; + + // Time the operation was originally scheduled via a StartNexusOperation request. + google.protobuf.Timestamp schedule_time = 12; + // Scheduled time + schedule to close timeout. + google.protobuf.Timestamp expiration_time = 13; + // Time when the operation transitioned to a closed state. + google.protobuf.Timestamp close_time = 14; + + // The time when the last attempt completed. + google.protobuf.Timestamp last_attempt_complete_time = 15; + // The last attempt's failure, if any. + temporal.api.failure.v1.Failure last_attempt_failure = 16; + // The time when the next attempt is scheduled. + google.protobuf.Timestamp next_attempt_schedule_time = 17; + + // Elapsed time from schedule_time to now for running operations or to close_time for closed + // operations, including all attempts and backoff between attempts. + google.protobuf.Duration execution_duration = 18; + + NexusOperationExecutionCancellationInfo cancellation_info = 19; + + // If the state is BLOCKED, blocked reason provides additional information. + string blocked_reason = 20; + + // Server-generated request ID used as an idempotency token when submitting start requests to + // the handler. Distinct from the request_id in StartNexusOperationRequest, which is the + // caller-side idempotency key for the StartNexusOperation RPC itself. + string request_id = 21; + + // Operation token. Only set for asynchronous operations after a successful StartOperation call. + string operation_token = 22; + + // Incremented each time the operation's state is mutated in persistence. + int64 state_transition_count = 23; + + temporal.api.common.v1.SearchAttributes search_attributes = 24; + + // Header for context propagation and tracing purposes. + map nexus_header = 25; + + // Metadata for use by user interfaces to display the fixed as-of-start summary and details of the operation. + temporal.api.sdk.v1.UserMetadata user_metadata = 26; + + // Links attached by the handler of this operation on start or completion. + repeated temporal.api.common.v1.Link links = 27; + + // The identity of the client who started this operation. + string identity = 28; + + // Updated once on scheduled and once on terminal status. + int64 state_size_bytes = 29; } // Limited Nexus operation information returned in the list response. // When adding fields here, ensure that it is also present in NexusOperationExecutionInfo (note that it may already be present in // NexusOperationExecutionInfo but not at the top-level). message NexusOperationExecutionListInfo { - // A unique identifier of this operation within its namespace along with run ID (below). - string operation_id = 1; - // The run ID of the standalone Nexus operation. - string run_id = 2; - - // Endpoint name. - string endpoint = 3; - // Service name. - string service = 4; - // Operation name. - string operation = 5; - - // Time the operation was originally scheduled via a StartNexusOperation request. - google.protobuf.Timestamp schedule_time = 6; - // If the operation is in a terminal status, this field represents the time the operation transitioned to that status. - google.protobuf.Timestamp close_time = 7; - // The status is updated once, when the operation is originally scheduled, and again when the operation reaches a terminal status. - temporal.api.enums.v1.NexusOperationExecutionStatus status = 8; - - // Search attributes from the start request. - temporal.api.common.v1.SearchAttributes search_attributes = 9; - - // Updated on terminal status. - int64 state_transition_count = 10; - // The difference between close time and scheduled time. - // This field is only populated if the operation is closed. - google.protobuf.Duration execution_duration = 11; + // A unique identifier of this operation within its namespace along with run ID (below). + string operation_id = 1; + // The run ID of the standalone Nexus operation. + string run_id = 2; + + // Endpoint name. + string endpoint = 3; + // Service name. + string service = 4; + // Operation name. + string operation = 5; + + // Time the operation was originally scheduled via a StartNexusOperation request. + google.protobuf.Timestamp schedule_time = 6; + // If the operation is in a terminal status, this field represents the time the operation transitioned to that status. + google.protobuf.Timestamp close_time = 7; + // The status is updated once, when the operation is originally scheduled, and again when the operation reaches a terminal status. + temporal.api.enums.v1.NexusOperationExecutionStatus status = 8; + + // Search attributes from the start request. + temporal.api.common.v1.SearchAttributes search_attributes = 9; + + // Updated on terminal status. + int64 state_transition_count = 10; + // The difference between close time and scheduled time. + // This field is only populated if the operation is closed. + google.protobuf.Duration execution_duration = 11; + + // Updated once on scheduled and once on terminal status. + int64 state_size_bytes = 12; } From ca11c86864328e5fe92a597b1f0e00975b1c30b9 Mon Sep 17 00:00:00 2001 From: sam Date: Thu, 28 May 2026 09:36:44 -0700 Subject: [PATCH 2/2] Undoes auto-fmting --- temporal/api/nexus/v1/message.proto | 581 ++++++++++++++-------------- 1 file changed, 291 insertions(+), 290 deletions(-) diff --git a/temporal/api/nexus/v1/message.proto b/temporal/api/nexus/v1/message.proto index 8133d4dab..a4e400c29 100644 --- a/temporal/api/nexus/v1/message.proto +++ b/temporal/api/nexus/v1/message.proto @@ -2,6 +2,13 @@ syntax = "proto3"; package temporal.api.nexus.v1; +option go_package = "go.temporal.io/api/nexus/v1;nexus"; +option java_package = "io.temporal.api.nexus.v1"; +option java_multiple_files = true; +option java_outer_classname = "MessageProto"; +option ruby_package = "Temporalio::Api::Nexus::V1"; +option csharp_namespace = "Temporalio.Api.Nexus.V1"; + import "google/protobuf/duration.proto"; import "google/protobuf/timestamp.proto"; import "temporal/api/common/v1/message.proto"; @@ -10,361 +17,355 @@ import "temporal/api/enums/v1/nexus.proto"; import "temporal/api/failure/v1/message.proto"; import "temporal/api/sdk/v1/user_metadata.proto"; -option csharp_namespace = "Temporalio.Api.Nexus.V1"; -option go_package = "go.temporal.io/api/nexus/v1;nexus"; -option java_multiple_files = true; -option java_outer_classname = "MessageProto"; -option java_package = "io.temporal.api.nexus.v1"; -option ruby_package = "Temporalio::Api::Nexus::V1"; - // A general purpose failure message. // See: https://github.com/nexus-rpc/api/blob/main/SPEC.md#failure message Failure { - string message = 1; - string stack_trace = 4; - map metadata = 2; - // UTF-8 encoded JSON serializable details. - bytes details = 3; - Failure cause = 5; + string message = 1; + string stack_trace = 4; + map metadata = 2; + // UTF-8 encoded JSON serializable details. + bytes details = 3; + Failure cause = 5; } message HandlerError { - // See https://github.com/nexus-rpc/api/blob/main/SPEC.md#predefined-handler-errors. - string error_type = 1; - Failure failure = 2; - // Retry behavior, defaults to the retry behavior of the error type as defined in the spec. - temporal.api.enums.v1.NexusHandlerErrorRetryBehavior retry_behavior = 3; + // See https://github.com/nexus-rpc/api/blob/main/SPEC.md#predefined-handler-errors. + string error_type = 1; + Failure failure = 2; + // Retry behavior, defaults to the retry behavior of the error type as defined in the spec. + temporal.api.enums.v1.NexusHandlerErrorRetryBehavior retry_behavior = 3; } message UnsuccessfulOperationError { - // See https://github.com/nexus-rpc/api/blob/main/SPEC.md#operationinfo. - string operation_state = 1; - Failure failure = 2; + // See https://github.com/nexus-rpc/api/blob/main/SPEC.md#operationinfo. + string operation_state = 1; + Failure failure = 2; } message Link { - // See https://github.com/nexus-rpc/api/blob/main/SPEC.md#links. - string url = 1; - string type = 2; + // See https://github.com/nexus-rpc/api/blob/main/SPEC.md#links. + string url = 1; + string type = 2; } // A request to start an operation. message StartOperationRequest { - // Name of service to start the operation in. - string service = 1; - // Type of operation to start. - string operation = 2; - // A request ID that can be used as an idempotentency key. - string request_id = 3; - // Callback URL to call upon completion if the started operation is async. - string callback = 4; - // Full request body from the incoming HTTP request. - temporal.api.common.v1.Payload payload = 5; - // Header that is expected to be attached to the callback request when the operation completes. - map callback_header = 6; - // Links contain caller information and can be attached to the operations started by the handler. - repeated Link links = 7; + // Name of service to start the operation in. + string service = 1; + // Type of operation to start. + string operation = 2; + // A request ID that can be used as an idempotentency key. + string request_id = 3; + // Callback URL to call upon completion if the started operation is async. + string callback = 4; + // Full request body from the incoming HTTP request. + temporal.api.common.v1.Payload payload = 5; + // Header that is expected to be attached to the callback request when the operation completes. + map callback_header = 6; + // Links contain caller information and can be attached to the operations started by the handler. + repeated Link links = 7; } // A request to cancel an operation. message CancelOperationRequest { - // Service name. - string service = 1; - // Type of operation to cancel. - string operation = 2; - // Operation ID as originally generated by a Handler. - // - // Deprecated. Renamed to operation_token. - string operation_id = 3 [deprecated = true]; - - // Operation token as originally generated by a Handler. - string operation_token = 4; + // Service name. + string service = 1; + // Type of operation to cancel. + string operation = 2; + // Operation ID as originally generated by a Handler. + // + // Deprecated. Renamed to operation_token. + string operation_id = 3 [deprecated = true]; + + // Operation token as originally generated by a Handler. + string operation_token = 4; } // A Nexus request. message Request { - message Capabilities { - // If set, handlers may use temporal.api.failure.v1.Failure instances to return failures to the server. - // This also allows handler and operation errors to have their own messages and stack traces. - bool temporal_failure_responses = 1; - } - - // Headers extracted from the original request in the Temporal frontend. - // When using Nexus over HTTP, this includes the request's HTTP headers ignoring multiple values. - map header = 1; - - // The timestamp when the request was scheduled in the frontend. - // (-- api-linter: core::0142::time-field-names=disabled - // aip.dev/not-precedent: Not following linter rules. --) - google.protobuf.Timestamp scheduled_time = 2; - - Capabilities capabilities = 100; - - oneof variant { - StartOperationRequest start_operation = 3; - CancelOperationRequest cancel_operation = 4; - } - - // The endpoint this request was addressed to before forwarding to the worker. - // Supported from server version 1.30.0. - string endpoint = 10; + message Capabilities { + // If set, handlers may use temporal.api.failure.v1.Failure instances to return failures to the server. + // This also allows handler and operation errors to have their own messages and stack traces. + bool temporal_failure_responses = 1; + } + + // Headers extracted from the original request in the Temporal frontend. + // When using Nexus over HTTP, this includes the request's HTTP headers ignoring multiple values. + map header = 1; + + // The timestamp when the request was scheduled in the frontend. + // (-- api-linter: core::0142::time-field-names=disabled + // aip.dev/not-precedent: Not following linter rules. --) + google.protobuf.Timestamp scheduled_time = 2; + + Capabilities capabilities = 100; + + oneof variant { + StartOperationRequest start_operation = 3; + CancelOperationRequest cancel_operation = 4; + } + + // The endpoint this request was addressed to before forwarding to the worker. + // Supported from server version 1.30.0. + string endpoint = 10; } // Response variant for StartOperationRequest. message StartOperationResponse { - // An operation completed successfully. - message Sync { - temporal.api.common.v1.Payload payload = 1; - repeated Link links = 2; - } - - // The operation will complete asynchronously. - // The returned ID can be used to reference this operation. - message Async { - // Deprecated. Renamed to operation_token. - string operation_id = 1 [deprecated = true]; - repeated Link links = 2; - string operation_token = 3; - } - - oneof variant { - Sync sync_success = 1; - Async async_success = 2; - // The operation completed unsuccessfully (failed or canceled). - // Deprecated. Use the failure variant instead. - UnsuccessfulOperationError operation_error = 3 [deprecated = true]; - // The operation completed unsuccessfully (failed or canceled). - // Failure object must contain an ApplicationFailureInfo or CanceledFailureInfo object. - temporal.api.failure.v1.Failure failure = 4; - } + // An operation completed successfully. + message Sync { + temporal.api.common.v1.Payload payload = 1; + repeated Link links = 2; + } + + // The operation will complete asynchronously. + // The returned ID can be used to reference this operation. + message Async { + // Deprecated. Renamed to operation_token. + string operation_id = 1 [deprecated = true]; + repeated Link links = 2; + string operation_token = 3; + } + + oneof variant { + Sync sync_success = 1; + Async async_success = 2; + // The operation completed unsuccessfully (failed or canceled). + // Deprecated. Use the failure variant instead. + UnsuccessfulOperationError operation_error = 3 [deprecated = true]; + // The operation completed unsuccessfully (failed or canceled). + // Failure object must contain an ApplicationFailureInfo or CanceledFailureInfo object. + temporal.api.failure.v1.Failure failure = 4; + } } // Response variant for CancelOperationRequest. -message CancelOperationResponse {} +message CancelOperationResponse { +} // A response indicating that the handler has successfully processed a request. message Response { - // Variant must correlate to the corresponding Request's variant. - oneof variant { - StartOperationResponse start_operation = 1; - CancelOperationResponse cancel_operation = 2; - } + // Variant must correlate to the corresponding Request's variant. + oneof variant { + StartOperationResponse start_operation = 1; + CancelOperationResponse cancel_operation = 2; + } } // A cluster-global binding from an endpoint ID to a target for dispatching incoming Nexus requests. message Endpoint { - // Data version for this endpoint, incremented for every update issued via the UpdateNexusEndpoint API. - int64 version = 1; - // Unique server-generated endpoint ID. - string id = 2; - // Spec for the endpoint. - EndpointSpec spec = 3; - - // The date and time when the endpoint was created. - // (-- api-linter: core::0142::time-field-names=disabled - // aip.dev/not-precedent: Not following linter rules. --) - google.protobuf.Timestamp created_time = 4; - - // The date and time when the endpoint was last modified. - // Will not be set if the endpoint has never been modified. - // (-- api-linter: core::0142::time-field-names=disabled - // aip.dev/not-precedent: Not following linter rules. --) - google.protobuf.Timestamp last_modified_time = 5; - - // Server exposed URL prefix for invocation of operations on this endpoint. - // This doesn't include the protocol, hostname or port as the server does not know how it should be accessed - // publicly. The URL is stable in the face of endpoint renames. - string url_prefix = 6; + // Data version for this endpoint, incremented for every update issued via the UpdateNexusEndpoint API. + int64 version = 1; + // Unique server-generated endpoint ID. + string id = 2; + // Spec for the endpoint. + EndpointSpec spec = 3; + + // The date and time when the endpoint was created. + // (-- api-linter: core::0142::time-field-names=disabled + // aip.dev/not-precedent: Not following linter rules. --) + google.protobuf.Timestamp created_time = 4; + + // The date and time when the endpoint was last modified. + // Will not be set if the endpoint has never been modified. + // (-- api-linter: core::0142::time-field-names=disabled + // aip.dev/not-precedent: Not following linter rules. --) + google.protobuf.Timestamp last_modified_time = 5; + + // Server exposed URL prefix for invocation of operations on this endpoint. + // This doesn't include the protocol, hostname or port as the server does not know how it should be accessed + // publicly. The URL is stable in the face of endpoint renames. + string url_prefix = 6; } // Contains mutable fields for an Endpoint. message EndpointSpec { - // Endpoint name, unique for this cluster. Must match `[a-zA-Z_][a-zA-Z0-9_]*`. - // Renaming an endpoint breaks all workflow callers that reference this endpoint, causing operations to fail. - string name = 1; + // Endpoint name, unique for this cluster. Must match `[a-zA-Z_][a-zA-Z0-9_]*`. + // Renaming an endpoint breaks all workflow callers that reference this endpoint, causing operations to fail. + string name = 1; - // Markdown description serialized as a single JSON string. - // If the Payload is encrypted, the UI and CLI may decrypt with the configured codec server endpoint. - // By default, the server enforces a limit of 20,000 bytes for this entire payload. - temporal.api.common.v1.Payload description = 2; + // Markdown description serialized as a single JSON string. + // If the Payload is encrypted, the UI and CLI may decrypt with the configured codec server endpoint. + // By default, the server enforces a limit of 20,000 bytes for this entire payload. + temporal.api.common.v1.Payload description = 2; - // Target to route requests to. - EndpointTarget target = 3; + // Target to route requests to. + EndpointTarget target = 3; } // Target to route requests to. message EndpointTarget { - // Target a worker polling on a Nexus task queue in a specific namespace. - message Worker { - // Namespace to route requests to. - string namespace = 1; - // Nexus task queue to route requests to. - string task_queue = 2; - } - - // Target an external server by URL. - // At a later point, this will support providing credentials, in the meantime, an http.RoundTripper can be injected - // into the server to modify the request. - message External { - // URL to call. - string url = 1; - } - - oneof variant { - Worker worker = 1; - External external = 2; - } + // Target a worker polling on a Nexus task queue in a specific namespace. + message Worker { + // Namespace to route requests to. + string namespace = 1; + // Nexus task queue to route requests to. + string task_queue = 2; + } + + // Target an external server by URL. + // At a later point, this will support providing credentials, in the meantime, an http.RoundTripper can be injected + // into the server to modify the request. + message External { + // URL to call. + string url = 1; + } + + oneof variant { + Worker worker = 1; + External external = 2; + } } // NexusOperationExecutionCancellationInfo contains the state of a Nexus operation cancellation. message NexusOperationExecutionCancellationInfo { - // The time when cancellation was requested. - google.protobuf.Timestamp requested_time = 1; + // The time when cancellation was requested. + google.protobuf.Timestamp requested_time = 1; - temporal.api.enums.v1.NexusOperationCancellationState state = 2; + temporal.api.enums.v1.NexusOperationCancellationState state = 2; - // The number of attempts made to deliver the cancel operation request. - // This number represents a minimum bound since the attempt is incremented after the request completes. - int32 attempt = 3; + // The number of attempts made to deliver the cancel operation request. + // This number represents a minimum bound since the attempt is incremented after the request completes. + int32 attempt = 3; - // The time when the last attempt completed. - google.protobuf.Timestamp last_attempt_complete_time = 4; - // The last attempt's failure, if any. - temporal.api.failure.v1.Failure last_attempt_failure = 5; - // The time when the next attempt is scheduled. - google.protobuf.Timestamp next_attempt_schedule_time = 6; + // The time when the last attempt completed. + google.protobuf.Timestamp last_attempt_complete_time = 4; + // The last attempt's failure, if any. + temporal.api.failure.v1.Failure last_attempt_failure = 5; + // The time when the next attempt is scheduled. + google.protobuf.Timestamp next_attempt_schedule_time = 6; - // If the state is BLOCKED, blocked reason provides additional information. - string blocked_reason = 7; + // If the state is BLOCKED, blocked reason provides additional information. + string blocked_reason = 7; - // A reason that may be specified in the CancelNexusOperationRequest. - string reason = 8; + // A reason that may be specified in the CancelNexusOperationRequest. + string reason = 8; } // Full current state of a standalone Nexus operation, as of the time of the request. message NexusOperationExecutionInfo { - // Unique identifier of this Nexus operation within its namespace along with run ID (below). - string operation_id = 1; - string run_id = 2; - - // Endpoint name, resolved to a URL via the cluster's endpoint registry. - string endpoint = 3; - // Service name. - string service = 4; - // Operation name. - string operation = 5; - - // A general status for this operation, indicates whether it is currently running or in one of the terminal statuses. - // Updated once when the operation is originally scheduled, and again when it reaches a terminal status. - temporal.api.enums.v1.NexusOperationExecutionStatus status = 6; - // More detailed breakdown of NEXUS_OPERATION_EXECUTION_STATUS_RUNNING. - temporal.api.enums.v1.PendingNexusOperationState state = 7; - - // Schedule-to-close timeout for this operation. - // (-- api-linter: core::0140::prepositions=disabled - // aip.dev/not-precedent: "to" is used to indicate interval. --) - google.protobuf.Duration schedule_to_close_timeout = 8; - - // Schedule-to-start timeout for this operation. - // (-- api-linter: core::0140::prepositions=disabled - // aip.dev/not-precedent: "to" is used to indicate interval. --) - google.protobuf.Duration schedule_to_start_timeout = 9; - - // Start-to-close timeout for this operation. - // (-- api-linter: core::0140::prepositions=disabled - // aip.dev/not-precedent: "to" is used to indicate interval. --) - google.protobuf.Duration start_to_close_timeout = 10; - - // The number of attempts made to deliver the start operation request. - // This number is approximate, it is incremented when a task is added to the history queue. - // In practice, there could be more attempts if a task is executed but fails to commit, or less attempts if a task - // was never executed. - int32 attempt = 11; - - // Time the operation was originally scheduled via a StartNexusOperation request. - google.protobuf.Timestamp schedule_time = 12; - // Scheduled time + schedule to close timeout. - google.protobuf.Timestamp expiration_time = 13; - // Time when the operation transitioned to a closed state. - google.protobuf.Timestamp close_time = 14; - - // The time when the last attempt completed. - google.protobuf.Timestamp last_attempt_complete_time = 15; - // The last attempt's failure, if any. - temporal.api.failure.v1.Failure last_attempt_failure = 16; - // The time when the next attempt is scheduled. - google.protobuf.Timestamp next_attempt_schedule_time = 17; - - // Elapsed time from schedule_time to now for running operations or to close_time for closed - // operations, including all attempts and backoff between attempts. - google.protobuf.Duration execution_duration = 18; - - NexusOperationExecutionCancellationInfo cancellation_info = 19; - - // If the state is BLOCKED, blocked reason provides additional information. - string blocked_reason = 20; - - // Server-generated request ID used as an idempotency token when submitting start requests to - // the handler. Distinct from the request_id in StartNexusOperationRequest, which is the - // caller-side idempotency key for the StartNexusOperation RPC itself. - string request_id = 21; - - // Operation token. Only set for asynchronous operations after a successful StartOperation call. - string operation_token = 22; - - // Incremented each time the operation's state is mutated in persistence. - int64 state_transition_count = 23; - - temporal.api.common.v1.SearchAttributes search_attributes = 24; - - // Header for context propagation and tracing purposes. - map nexus_header = 25; - - // Metadata for use by user interfaces to display the fixed as-of-start summary and details of the operation. - temporal.api.sdk.v1.UserMetadata user_metadata = 26; - - // Links attached by the handler of this operation on start or completion. - repeated temporal.api.common.v1.Link links = 27; - - // The identity of the client who started this operation. - string identity = 28; - - // Updated once on scheduled and once on terminal status. - int64 state_size_bytes = 29; + // Unique identifier of this Nexus operation within its namespace along with run ID (below). + string operation_id = 1; + string run_id = 2; + + // Endpoint name, resolved to a URL via the cluster's endpoint registry. + string endpoint = 3; + // Service name. + string service = 4; + // Operation name. + string operation = 5; + + // A general status for this operation, indicates whether it is currently running or in one of the terminal statuses. + // Updated once when the operation is originally scheduled, and again when it reaches a terminal status. + temporal.api.enums.v1.NexusOperationExecutionStatus status = 6; + // More detailed breakdown of NEXUS_OPERATION_EXECUTION_STATUS_RUNNING. + temporal.api.enums.v1.PendingNexusOperationState state = 7; + + // Schedule-to-close timeout for this operation. + // (-- api-linter: core::0140::prepositions=disabled + // aip.dev/not-precedent: "to" is used to indicate interval. --) + google.protobuf.Duration schedule_to_close_timeout = 8; + + // Schedule-to-start timeout for this operation. + // (-- api-linter: core::0140::prepositions=disabled + // aip.dev/not-precedent: "to" is used to indicate interval. --) + google.protobuf.Duration schedule_to_start_timeout = 9; + + // Start-to-close timeout for this operation. + // (-- api-linter: core::0140::prepositions=disabled + // aip.dev/not-precedent: "to" is used to indicate interval. --) + google.protobuf.Duration start_to_close_timeout = 10; + + // The number of attempts made to deliver the start operation request. + // This number is approximate, it is incremented when a task is added to the history queue. + // In practice, there could be more attempts if a task is executed but fails to commit, or less attempts if a task + // was never executed. + int32 attempt = 11; + + // Time the operation was originally scheduled via a StartNexusOperation request. + google.protobuf.Timestamp schedule_time = 12; + // Scheduled time + schedule to close timeout. + google.protobuf.Timestamp expiration_time = 13; + // Time when the operation transitioned to a closed state. + google.protobuf.Timestamp close_time = 14; + + // The time when the last attempt completed. + google.protobuf.Timestamp last_attempt_complete_time = 15; + // The last attempt's failure, if any. + temporal.api.failure.v1.Failure last_attempt_failure = 16; + // The time when the next attempt is scheduled. + google.protobuf.Timestamp next_attempt_schedule_time = 17; + + // Elapsed time from schedule_time to now for running operations or to close_time for closed + // operations, including all attempts and backoff between attempts. + google.protobuf.Duration execution_duration = 18; + + NexusOperationExecutionCancellationInfo cancellation_info = 19; + + // If the state is BLOCKED, blocked reason provides additional information. + string blocked_reason = 20; + + // Server-generated request ID used as an idempotency token when submitting start requests to + // the handler. Distinct from the request_id in StartNexusOperationRequest, which is the + // caller-side idempotency key for the StartNexusOperation RPC itself. + string request_id = 21; + + // Operation token. Only set for asynchronous operations after a successful StartOperation call. + string operation_token = 22; + + // Incremented each time the operation's state is mutated in persistence. + int64 state_transition_count = 23; + + temporal.api.common.v1.SearchAttributes search_attributes = 24; + + // Header for context propagation and tracing purposes. + map nexus_header = 25; + + // Metadata for use by user interfaces to display the fixed as-of-start summary and details of the operation. + temporal.api.sdk.v1.UserMetadata user_metadata = 26; + + // Links attached by the handler of this operation on start or completion. + repeated temporal.api.common.v1.Link links = 27; + + // The identity of the client who started this operation. + string identity = 28; + + // Updated once on scheduled and once on terminal status. + int64 state_size_bytes = 29; } // Limited Nexus operation information returned in the list response. // When adding fields here, ensure that it is also present in NexusOperationExecutionInfo (note that it may already be present in // NexusOperationExecutionInfo but not at the top-level). message NexusOperationExecutionListInfo { - // A unique identifier of this operation within its namespace along with run ID (below). - string operation_id = 1; - // The run ID of the standalone Nexus operation. - string run_id = 2; - - // Endpoint name. - string endpoint = 3; - // Service name. - string service = 4; - // Operation name. - string operation = 5; - - // Time the operation was originally scheduled via a StartNexusOperation request. - google.protobuf.Timestamp schedule_time = 6; - // If the operation is in a terminal status, this field represents the time the operation transitioned to that status. - google.protobuf.Timestamp close_time = 7; - // The status is updated once, when the operation is originally scheduled, and again when the operation reaches a terminal status. - temporal.api.enums.v1.NexusOperationExecutionStatus status = 8; - - // Search attributes from the start request. - temporal.api.common.v1.SearchAttributes search_attributes = 9; - - // Updated on terminal status. - int64 state_transition_count = 10; - // The difference between close time and scheduled time. - // This field is only populated if the operation is closed. - google.protobuf.Duration execution_duration = 11; - - // Updated once on scheduled and once on terminal status. - int64 state_size_bytes = 12; + // A unique identifier of this operation within its namespace along with run ID (below). + string operation_id = 1; + // The run ID of the standalone Nexus operation. + string run_id = 2; + + // Endpoint name. + string endpoint = 3; + // Service name. + string service = 4; + // Operation name. + string operation = 5; + + // Time the operation was originally scheduled via a StartNexusOperation request. + google.protobuf.Timestamp schedule_time = 6; + // If the operation is in a terminal status, this field represents the time the operation transitioned to that status. + google.protobuf.Timestamp close_time = 7; + // The status is updated once, when the operation is originally scheduled, and again when the operation reaches a terminal status. + temporal.api.enums.v1.NexusOperationExecutionStatus status = 8; + + // Search attributes from the start request. + temporal.api.common.v1.SearchAttributes search_attributes = 9; + + // Updated on terminal status. + int64 state_transition_count = 10; + // The difference between close time and scheduled time. + // This field is only populated if the operation is closed. + google.protobuf.Duration execution_duration = 11; + + // Updated once on scheduled and once on terminal status. + int64 state_size_bytes = 12; }