diff --git a/openapi/openapiv2.json b/openapi/openapiv2.json index 97ff181c9..2f020a07d 100644 --- a/openapi/openapiv2.json +++ b/openapi/openapiv2.json @@ -10717,6 +10717,10 @@ "type": "object", "description": "Trigger for when the activity is closed." }, + "CallbackInfoOperationCompleted": { + "type": "object", + "description": "Trigger for when the Nexus operation is completed, covering both success cases as\nwell as any type of failure." + }, "CallbackInfoUpdateWorkflowExecutionCompleted": { "type": "object", "properties": { @@ -10834,20 +10838,6 @@ }, "description": "Target an external server by URL.\nAt a later point, this will support providing credentials, in the meantime, an http.RoundTripper can be injected\ninto the server to modify the request." }, - "EndpointTargetWorker": { - "type": "object", - "properties": { - "namespace": { - "type": "string", - "description": "Namespace to route requests to." - }, - "taskQueue": { - "type": "string", - "description": "Nexus task queue to route requests to." - } - }, - "description": "Target a worker polling on a Nexus task queue in a specific namespace." - }, "EventGroupMarkerInboundEvent": { "type": "object", "properties": { @@ -10906,6 +10896,21 @@ }, "description": "A link to a standalone Nexus operation." }, + "LinkNexusOperationCallback": { + "type": "object", + "properties": { + "operationId": { + "type": "string" + }, + "runId": { + "type": "string" + }, + "requestId": { + "type": "string" + } + }, + "description": "A link to a worker callback attached to a Nexus operation within the same namespace. e.g. the completion handler attached\nto a standalone Nexus operation, not the source Nexus operation itself. A standalone Nexus operation can have multiple\ncallbacks attached to them, and will be differentiated by the server-generated request_id used when the callback was invoked." + }, "LinkWorkflow": { "type": "object", "properties": { @@ -12455,6 +12460,10 @@ "$ref": "#/definitions/v1NexusOperationIdConflictPolicy", "description": "Defines how to resolve an operation id conflict with a *running* operation.\nThe default policy is NEXUS_OPERATION_ID_CONFLICT_POLICY_FAIL." }, + "onConflictOptions": { + "$ref": "#/definitions/apiNexusoperationV1OnConflictOptions", + "description": "Defines actions to be done to the existing running standalone Nexus when the conflict policy\nNEXUS_OPERATION_ID_CONFLICT_POLICY_USE_EXISTING is used. If not set or set to a empty object\n(all options with default value), it won't do modify running operation." + }, "searchAttributes": { "$ref": "#/definitions/v1SearchAttributes", "description": "Search attributes for indexing." @@ -12469,6 +12478,14 @@ "userMetadata": { "$ref": "#/definitions/v1UserMetadata", "description": "Metadata for use by user interfaces to display the fixed as-of-start summary and details of the operation." + }, + "completionCallbacks": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Callback" + }, + "description": "Completion callbacks to be invoked once the Nexus operation reaches a terminal state." } } }, @@ -13227,6 +13244,10 @@ "blockedReason": { "type": "string", "description": "If the state is BLOCKED, blocked reason provides additional information." + }, + "outcome": { + "$ref": "#/definitions/v1CallbackExecutionOutcome", + "description": "Result of the callback's execution, only set when the callback reaches a terminal state." } }, "description": "Common callback information. Specific CallbackInfo messages should embed this and may include additional fields." @@ -13249,6 +13270,42 @@ }, "description": "When starting an execution with a conflict policy that uses an existing execution and there is already an existing\nrunning execution, OnConflictOptions defines actions to be taken on the existing running execution." }, + "apiNexusoperationV1CallbackInfo": { + "type": "object", + "properties": { + "trigger": { + "$ref": "#/definitions/apiNexusoperationV1CallbackInfoTrigger", + "description": "Trigger for this callback." + }, + "info": { + "$ref": "#/definitions/apiCallbackV1CallbackInfo", + "description": "Common callback info." + } + }, + "description": "CallbackInfo contains the state of a callback attached to a standalone Nexus operation." + }, + "apiNexusoperationV1CallbackInfoTrigger": { + "type": "object", + "properties": { + "operationCompleted": { + "$ref": "#/definitions/CallbackInfoOperationCompleted" + } + } + }, + "apiNexusoperationV1OnConflictOptions": { + "type": "object", + "properties": { + "attachCompletionCallbacks": { + "type": "boolean", + "description": "Attaches the completion callbacks to the running operation." + }, + "attachLinks": { + "type": "boolean", + "description": "Attaches the links to the WorkflowExecutionOptionsUpdatedEvent history event." + } + }, + "description": "When StartNexusOperationExecutionRequest uses the conflict policy NEXUS_OPERATION_ID_CONFLICT_POLICY_USE_EXISTING\nand there is already an existing, running standalone Nexus operation, OnConflictOptions defines actions to be\ntaken." + }, "apiWorkflowV1CallbackInfo": { "type": "object", "properties": { @@ -14406,6 +14463,9 @@ "internal": { "$ref": "#/definitions/CallbackInternal" }, + "worker": { + "$ref": "#/definitions/v1CallbackWorker" + }, "links": { "type": "array", "items": { @@ -14417,6 +14477,20 @@ }, "description": "Callback to attach to various events in the system, e.g. workflow run completion." }, + "v1CallbackExecutionOutcome": { + "type": "object", + "properties": { + "success": { + "type": "object", + "properties": {}, + "title": "The callback completed successfully. (Which may include delivering a \"failed\" result successfully.)" + }, + "failure": { + "$ref": "#/definitions/v1Failure", + "description": "The failure if the callback was not able to complete successfully. e.g. timed out, received an\nunretriable error, etc." + } + } + }, "v1CallbackState": { "type": "string", "enum": [ @@ -14429,7 +14503,31 @@ "CALLBACK_STATE_BLOCKED" ], "default": "CALLBACK_STATE_UNSPECIFIED", - "description": "State of a callback.\n\n - CALLBACK_STATE_UNSPECIFIED: Default value, unspecified state.\n - CALLBACK_STATE_STANDBY: Callback is standing by, waiting to be triggered.\n - CALLBACK_STATE_SCHEDULED: Callback is in the queue waiting to be executed or is currently executing.\n - CALLBACK_STATE_BACKING_OFF: Callback has failed with a retryable error and is backing off before the next attempt.\n - CALLBACK_STATE_FAILED: Callback has failed.\n - CALLBACK_STATE_SUCCEEDED: Callback has succeeded.\n - CALLBACK_STATE_BLOCKED: Callback is blocked (eg: by circuit breaker)." + "description": "State of a callback.\n\n - CALLBACK_STATE_UNSPECIFIED: Default value, unspecified state.\n - CALLBACK_STATE_STANDBY: Callback is standing by, waiting to be triggered.\n - CALLBACK_STATE_SCHEDULED: Callback is in the queue waiting to be executed or is currently executing.\n - CALLBACK_STATE_BACKING_OFF: Callback has failed with a retryable error and is backing off before the next attempt.\n - CALLBACK_STATE_FAILED: Callback has failed.\n - CALLBACK_STATE_SUCCEEDED: Callback has succeeded.\n - CALLBACK_STATE_BLOCKED: Callback is blocked, e.g. by circuit breaker." + }, + "v1CallbackWorker": { + "type": "object", + "properties": { + "taskQueueName": { + "type": "string", + "description": "Nexus task queue the Temporal worker is listening on.\n\nNOTE: This is not a temporal.api.taskqueue.v1.TaskQueue to avoid a circular dependency." + }, + "service": { + "type": "string", + "description": "Target Nexus service, e.g. \"HTTPAdapter\"." + }, + "operation": { + "type": "string", + "description": "Target operation, e.g. \"DeliverAsWebhook\"." + }, + "sourceContext": { + "$ref": "#/definitions/v1Payload", + "description": "There is a relatively small maximum size the source context can be, e.g. 32KiB.", + "title": "Arbitrary user-supplied data from the source operation's callsite. (As applicable, not all operations\nsupport attaching context data.)" + } + }, + "description": "The targeted Nexus service must be registered within the same namespace as the source operation\nthe callback is attached to. (While Nexus allows for cross-namespace operations, worker callbacks\nare purely \"caller-side\".)\n\nWorker callbacks are only supported for certain types of operations, e.g. standalone Nexus operations.\nAttempting to attach a Worker callback for an unsupported operation will result in an INVALID_ARGUMENT\nerror from the server.", + "title": "Worker callbacks are requests to invoke a specific shape of Nexus operation on a Temporal worker.\nThe specified Nexus operation must have the following:\n- Input: temporal.api.notificationservice.v1.OnCompleteRequest\n- Output: temporal.api.notificationservice.v1.OnCompleteResponse" }, "v1CancelExternalWorkflowExecutionFailedCause": { "type": "string", @@ -15354,6 +15452,14 @@ "type": "string", "format": "byte", "description": "Token for follow-on long-poll requests. Absent only if the operation is complete." + }, + "completionCallbacks": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/apiNexusoperationV1CallbackInfo" + }, + "description": "Completion callbacks to be invoked once the Nexus operation reaches a terminal state.\nThey will remain in the CALLBACK_STATE_STANDBY state until the Nexus operation is finished." } } }, @@ -15591,7 +15697,7 @@ "type": "object", "properties": { "worker": { - "$ref": "#/definitions/EndpointTargetWorker" + "$ref": "#/definitions/v1EndpointTargetWorker" }, "external": { "$ref": "#/definitions/EndpointTargetExternal" @@ -15599,6 +15705,20 @@ }, "description": "Target to route requests to." }, + "v1EndpointTargetWorker": { + "type": "object", + "properties": { + "namespace": { + "type": "string", + "description": "Namespace to route requests to." + }, + "taskQueue": { + "type": "string", + "description": "Nexus task queue to route requests to." + } + }, + "description": "Target a worker polling on a Nexus task queue in a specific namespace." + }, "v1EventGroupMarker": { "type": "object", "properties": { @@ -16427,6 +16547,9 @@ }, "workflow": { "$ref": "#/definitions/LinkWorkflow" + }, + "nexusOperationCallback": { + "$ref": "#/definitions/LinkNexusOperationCallback" } }, "description": "Link can be associated with history events. It might contain information about an external entity\nrelated to the history event. For example, workflow A makes a Nexus call that starts workflow B:\nin this case, a history event in workflow A could contain a Link to the workflow started event in\nworkflow B, and vice-versa." diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index f2081bd9b..dd967d148 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -10748,6 +10748,8 @@ components: $ref: '#/components/schemas/Callback_Nexus' internal: $ref: '#/components/schemas/Callback_Internal' + worker: + $ref: '#/components/schemas/Callback_Worker' links: type: array items: @@ -10756,6 +10758,15 @@ components: Links associated with the callback. It can be used to link to underlying resources of the callback. description: Callback to attach to various events in the system, e.g. workflow run completion. + CallbackExecutionOutcome: + type: object + properties: + failure: + allOf: + - $ref: '#/components/schemas/Failure' + description: |- + The failure if the callback was not able to complete successfully. e.g. timed out, received an + unretriable error, etc. CallbackInfo: type: object properties: @@ -10800,6 +10811,10 @@ components: blockedReason: type: string description: If the state is BLOCKED, blocked reason provides additional information. + outcome: + allOf: + - $ref: '#/components/schemas/CallbackExecutionOutcome' + description: Result of the callback's execution, only set when the callback reaches a terminal state. description: Common callback information. Specific CallbackInfo messages should embed this and may include additional fields. Callback_Internal: type: object @@ -10824,6 +10839,42 @@ components: additionalProperties: type: string description: Header to attach to callback request. + Callback_Worker: + type: object + properties: + taskQueueName: + type: string + description: |- + Nexus task queue the Temporal worker is listening on. + + NOTE: This is not a temporal.api.taskqueue.v1.TaskQueue to avoid a circular dependency. + service: + type: string + description: Target Nexus service, e.g. "HTTPAdapter". + operation: + type: string + description: Target operation, e.g. "DeliverAsWebhook". + sourceContext: + allOf: + - $ref: '#/components/schemas/Payload' + description: |- + Arbitrary user-supplied data from the source operation's callsite. (As applicable, not all operations + support attaching context data.) + + There is a relatively small maximum size the source context can be, e.g. 32KiB. + description: |- + Worker callbacks are requests to invoke a specific shape of Nexus operation on a Temporal worker. + The specified Nexus operation must have the following: + - Input: temporal.api.notificationservice.v1.OnCompleteRequest + - Output: temporal.api.notificationservice.v1.OnCompleteResponse + + The targeted Nexus service must be registered within the same namespace as the source operation + the callback is attached to. (While Nexus allows for cross-namespace operations, worker callbacks + are purely "caller-side".) + + Worker callbacks are only supported for certain types of operations, e.g. standalone Nexus operations. + Attempting to attach a Worker callback for an unsupported operation will result in an INVALID_ARGUMENT + error from the server. CanceledFailureInfo: type: object properties: @@ -11808,6 +11859,13 @@ components: type: string description: Token for follow-on long-poll requests. Absent only if the operation is complete. format: bytes + completionCallbacks: + type: array + items: + $ref: '#/components/schemas/CallbackInfo' + description: |- + Completion callbacks to be invoked once the Nexus operation reaches a terminal state. + They will remain in the CALLBACK_STATE_STANDBY state until the Nexus operation is finished. DescribeScheduleResponse: type: object properties: @@ -12841,6 +12899,8 @@ components: $ref: '#/components/schemas/Link_NexusOperation' workflow: $ref: '#/components/schemas/Link_Workflow' + nexusOperationCallback: + $ref: '#/components/schemas/Link_NexusOperationCallback' description: |- Link can be associated with history events. It might contain information about an external entity related to the history event. For example, workflow A makes a Nexus call that starts workflow B: @@ -12875,6 +12935,19 @@ components: runId: type: string description: A link to a standalone Nexus operation. + Link_NexusOperationCallback: + type: object + properties: + operationId: + type: string + runId: + type: string + requestId: + type: string + description: |- + A link to a worker callback attached to a Nexus operation within the same namespace. e.g. the completion handler attached + to a standalone Nexus operation, not the source Nexus operation itself. A standalone Nexus operation can have multiple + callbacks attached to them, and will be differentiated by the server-generated request_id used when the callback was invoked. Link_Workflow: type: object properties: @@ -17041,6 +17114,13 @@ components: Defines how to resolve an operation id conflict with a *running* operation. The default policy is NEXUS_OPERATION_ID_CONFLICT_POLICY_FAIL. format: enum + onConflictOptions: + allOf: + - $ref: '#/components/schemas/OnConflictOptions' + description: |- + Defines actions to be done to the existing running standalone Nexus when the conflict policy + NEXUS_OPERATION_ID_CONFLICT_POLICY_USE_EXISTING is used. If not set or set to a empty object + (all options with default value), it won't do modify running operation. searchAttributes: allOf: - $ref: '#/components/schemas/SearchAttributes' @@ -17060,6 +17140,11 @@ components: allOf: - $ref: '#/components/schemas/UserMetadata' description: Metadata for use by user interfaces to display the fixed as-of-start summary and details of the operation. + completionCallbacks: + type: array + items: + $ref: '#/components/schemas/Callback' + description: Completion callbacks to be invoked once the Nexus operation reaches a terminal state. StartNexusOperationExecutionResponse: type: object properties: diff --git a/temporal/api/callback/v1/message.proto b/temporal/api/callback/v1/message.proto index f881a4eef..7803d5a20 100644 --- a/temporal/api/callback/v1/message.proto +++ b/temporal/api/callback/v1/message.proto @@ -9,6 +9,7 @@ option java_outer_classname = "MessageProto"; option ruby_package = "Temporalio::Api::Callback::V1"; option csharp_namespace = "Temporalio.Api.Callback.V1"; +import "google/protobuf/empty.proto"; import "google/protobuf/timestamp.proto"; import "temporal/api/common/v1/message.proto"; @@ -34,4 +35,17 @@ message CallbackInfo { google.protobuf.Timestamp next_attempt_schedule_time = 7; // If the state is BLOCKED, blocked reason provides additional information. string blocked_reason = 8; -} \ No newline at end of file + + // Result of the callback's execution, only set when the callback reaches a terminal state. + CallbackExecutionOutcome outcome = 9; +} + +message CallbackOutcome { + oneof value { + // The callback completed successfully. (Which may include delivering a "failed" result successfully.) + google.protobuf.Empty success = 1; + // The failure if the callback was not able to complete successfully. e.g. timed out, received an + // unretriable error, etc. + temporal.api.failure.v1.Failure failure = 2; + } +} diff --git a/temporal/api/common/v1/message.proto b/temporal/api/common/v1/message.proto index 1af5b4acc..e7f2c291c 100644 --- a/temporal/api/common/v1/message.proto +++ b/temporal/api/common/v1/message.proto @@ -201,10 +201,41 @@ message Callback { bytes data = 1; } + // Worker callbacks are requests to invoke a specific shape of Nexus operation on a Temporal worker. + // The specified Nexus operation must have the following: + // - Input: temporal.api.notificationservice.v1.OnCompleteRequest + // - Output: temporal.api.notificationservice.v1.OnCompleteResponse + // + // The targeted Nexus service must be registered within the same namespace as the source operation + // the callback is attached to. (While Nexus allows for cross-namespace operations, worker callbacks + // are purely "caller-side".) + // + // Worker callbacks are only supported for certain types of operations, e.g. standalone Nexus operations. + // Attempting to attach a Worker callback for an unsupported operation will result in an INVALID_ARGUMENT + // error from the server. + message Worker { + // Nexus task queue the Temporal worker is listening on. + // + // NOTE: This is not a temporal.api.taskqueue.v1.TaskQueue to avoid a circular dependency. + string task_queue_name = 1; + + // Target Nexus service, e.g. "HTTPAdapter". + string service = 2; + // Target operation, e.g. "DeliverAsWebhook". + string operation = 3; + + // Arbitrary user-supplied data from the source operation's callsite. (As applicable, not all operations + // support attaching context data.) + // + // There is a relatively small maximum size the source context can be, e.g. 32KiB. + temporal.api.common.v1.Payload source_context = 4; + } + reserved 1; // For a generic callback mechanism to be added later. oneof variant { Nexus nexus = 2; Internal internal = 3; + Worker worker = 4; } // Links associated with the callback. It can be used to link to underlying resources of the @@ -273,12 +304,22 @@ message Link { string reason = 4; } + // A link to a worker callback attached to a Nexus operation within the same namespace. e.g. the completion handler attached + // to a standalone Nexus operation, not the source Nexus operation itself. A standalone Nexus operation can have multiple + // callbacks attached to them, and will be differentiated by the server-generated request_id used when the callback was invoked. + message NexusOperationCallback { + string operation_id = 1; + string run_id = 2; + string request_id = 3; + } + oneof variant { WorkflowEvent workflow_event = 1; BatchJob batch_job = 2; Activity activity = 3; NexusOperation nexus_operation = 4; Workflow workflow = 5; + NexusOperationCallback nexus_operation_callback = 6; } } diff --git a/temporal/api/enums/v1/common.proto b/temporal/api/enums/v1/common.proto index cdc387173..e2929337e 100644 --- a/temporal/api/enums/v1/common.proto +++ b/temporal/api/enums/v1/common.proto @@ -47,7 +47,7 @@ enum CallbackState { CALLBACK_STATE_FAILED = 4; // Callback has succeeded. CALLBACK_STATE_SUCCEEDED = 5; - // Callback is blocked (eg: by circuit breaker). + // Callback is blocked, e.g. by circuit breaker. CALLBACK_STATE_BLOCKED = 6; } diff --git a/temporal/api/nexusoperation/v1/message.proto b/temporal/api/nexusoperation/v1/message.proto new file mode 100644 index 000000000..f247013b0 --- /dev/null +++ b/temporal/api/nexusoperation/v1/message.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; + +package temporal.api.nexusoperation.v1; + +option go_package = "go.temporal.io/api/nexusoperation/v1;nexusoperation"; +option java_package = "io.temporal.api.nexusoperation.v1"; +option java_multiple_files = true; +option java_outer_classname = "MessageProto"; +option ruby_package = "Temporalio::Api::NexusOperation::V1"; +option csharp_namespace = "Temporalio.Api.NexusOperation.V1"; + +import "temporal/api/callback/v1/message.proto"; + +// CallbackInfo contains the state of a callback attached to a standalone Nexus operation. +message CallbackInfo { + // Trigger for when the Nexus operation is completed, covering both success cases as + // well as any type of failure. + message OperationCompleted {} + + message Trigger { + oneof variant { + OperationCompleted operation_completed = 1; + } + } + + // Trigger for this callback. + Trigger trigger = 1; + // Common callback info. + temporal.api.callback.v1.CallbackInfo info = 2; +} + +// When StartNexusOperationExecutionRequest uses the conflict policy NEXUS_OPERATION_ID_CONFLICT_POLICY_USE_EXISTING +// and there is already an existing, running standalone Nexus operation, OnConflictOptions defines actions to be +// taken. +message OnConflictOptions { + // Attaches the request ID to the running operation. + bool attach_request_id = 1; + // Attaches the completion callbacks to the running operation. + bool attach_completion_callbacks = 2; + // Attaches any new links to the running operation. + bool attach_links = 3; +} diff --git a/temporal/api/notificationservice/v1/request_response.proto b/temporal/api/notificationservice/v1/request_response.proto new file mode 100644 index 000000000..edf861c77 --- /dev/null +++ b/temporal/api/notificationservice/v1/request_response.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; + +package temporal.api.notificationservice.v1; + +option go_package = "go.temporal.io/api/notificationservice/v1;notificationservice"; +option java_package = "io.temporal.api.notificationservice.v1"; +option java_multiple_files = true; +option java_outer_classname = "RequestResponseProto"; +option ruby_package = "Temporalio::Api::NotificationService::V1"; +option csharp_namespace = "Temporalio.Api.NotificationService.V1"; + +import "temporal/api/common/v1/message.proto"; +import "temporal/api/failure/v1/message.proto"; + +// OnCompleteRequest is the request type to the NotificationService's OnComplete operation, +// allowing for defining completion handlers for arbitrary asynchronous operations. +// +// Information about the source operation will be available in the form of a commonpb.Link, +// which will be available separately from this OnCompleteRequest. e.g. a link to the source +// standalone Nexus operation would be found in the nexuspb.StartOperationRequest parameter +// sent to the worker callback. (In addition to this OnCompleteRequest.) +message OnCompleteRequest { + + // The outcome of the source operation. + message Outcome { + oneof result { + // The operation was successful, and resulted in the given payload(s). + temporal.api.common.v1.Payloads success = 1; + // The operation failed. Includes timeout, cancellation, and application errors. + temporal.api.failure.v1.Failure failure = 2; + } + } + Outcome outcome = 1; + + // User-supplied data which was added to the source invocation. (As applicable.) + temporal.api.common.v1.Payload source_context = 2; +} + +// OnCompleteResponse is the return type of the OnComplete operation. +message OnCompleteResponse {} diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index 66f478c5c..15526ba74 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -44,6 +44,7 @@ import "temporal/api/batch/v1/message.proto"; import "temporal/api/sdk/v1/task_complete_metadata.proto"; import "temporal/api/sdk/v1/user_metadata.proto"; import "temporal/api/nexus/v1/message.proto"; +import "temporal/api/nexusoperation/v1/message.proto"; import "temporal/api/worker/v1/message.proto"; import "google/protobuf/duration.proto"; @@ -3381,6 +3382,10 @@ message StartNexusOperationExecutionRequest { // Defines how to resolve an operation id conflict with a *running* operation. // The default policy is NEXUS_OPERATION_ID_CONFLICT_POLICY_FAIL. temporal.api.enums.v1.NexusOperationIdConflictPolicy id_conflict_policy = 13; + // Defines actions to be done to the existing running standalone Nexus when the conflict policy + // NEXUS_OPERATION_ID_CONFLICT_POLICY_USE_EXISTING is used. If not set or set to a empty object + // (all options with default value), it won't do modify running operation. + temporal.api.nexusoperation.v1.OnConflictOptions on_conflict_options = 17; // Search attributes for indexing. temporal.api.common.v1.SearchAttributes search_attributes = 14; @@ -3393,6 +3398,9 @@ message StartNexusOperationExecutionRequest { map nexus_header = 15; // 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 = 16; + + // Completion callbacks to be invoked once the Nexus operation reaches a terminal state. + repeated temporal.api.common.v1.Callback completion_callbacks = 18; } message StartNexusOperationExecutionResponse { @@ -3441,6 +3449,10 @@ message DescribeNexusOperationExecutionResponse { // Token for follow-on long-poll requests. Absent only if the operation is complete. bytes long_poll_token = 6; + + // Completion callbacks to be invoked once the Nexus operation reaches a terminal state. + // They will remain in the CALLBACK_STATE_STANDBY state until the Nexus operation is finished. + repeated temporal.api.nexusoperation.v1.CallbackInfo completion_callbacks = 7; } message PollNexusOperationExecutionRequest {