Skip to content

Commit b4a09df

Browse files
authored
Merge branch 'master' into fredtzeng/saa-start-delay
2 parents 47fdfcd + 84b0a5f commit b4a09df

9 files changed

Lines changed: 3446 additions & 525 deletions

File tree

openapi/openapiv2.json

Lines changed: 1728 additions & 507 deletions
Large diffs are not rendered by default.

openapi/openapiv3.yaml

Lines changed: 1149 additions & 13 deletions
Large diffs are not rendered by default.

temporal/api/common/v1/message.proto

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,10 +247,18 @@ message Link {
247247
string run_id = 3;
248248
}
249249

250+
// A link to a standalone Nexus operation.
251+
message NexusOperation {
252+
string namespace = 1;
253+
string operation_id = 2;
254+
string run_id = 3;
255+
}
256+
250257
oneof variant {
251258
WorkflowEvent workflow_event = 1;
252259
BatchJob batch_job = 2;
253260
Activity activity = 3;
261+
NexusOperation nexus_operation = 4;
254262
}
255263
}
256264

temporal/api/enums/v1/nexus.proto

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,63 @@ enum NexusHandlerErrorRetryBehavior {
2020
NEXUS_HANDLER_ERROR_RETRY_BEHAVIOR_NON_RETRYABLE = 2;
2121
}
2222

23+
// Status of a standalone Nexus operation execution.
24+
// The status is updated once, when the operation is originally scheduled, and again when the
25+
// operation reaches a terminal status.
26+
// (-- api-linter: core::0216::synonyms=disabled
27+
// aip.dev/not-precedent: Named consistently with WorkflowExecutionStatus. --)
28+
enum NexusOperationExecutionStatus {
29+
NEXUS_OPERATION_EXECUTION_STATUS_UNSPECIFIED = 0;
30+
// The operation is not in a terminal status. The operation may be attempting to start,
31+
// backing off between attempts, or already started.
32+
NEXUS_OPERATION_EXECUTION_STATUS_RUNNING = 1;
33+
// The operation completed successfully.
34+
NEXUS_OPERATION_EXECUTION_STATUS_COMPLETED = 2;
35+
// The operation completed with failure.
36+
NEXUS_OPERATION_EXECUTION_STATUS_FAILED = 3;
37+
// The operation completed as canceled.
38+
// Requesting to cancel an operation does not automatically transition the operation to canceled status, depending
39+
// on the current operation status and the cancelation type used.
40+
NEXUS_OPERATION_EXECUTION_STATUS_CANCELED = 4;
41+
// The operation was terminated. Termination happens immediately without notifying the handler.
42+
NEXUS_OPERATION_EXECUTION_STATUS_TERMINATED = 5;
43+
// The operation has timed out by reaching one of the specified timeouts.
44+
NEXUS_OPERATION_EXECUTION_STATUS_TIMED_OUT = 6;
45+
}
46+
47+
// Stage that can be specified when waiting on a nexus operation.
48+
enum NexusOperationWaitStage {
49+
NEXUS_OPERATION_WAIT_STAGE_UNSPECIFIED = 0;
50+
// Wait for the operation to be started.
51+
NEXUS_OPERATION_WAIT_STAGE_STARTED = 1;
52+
// Wait for the operation to be in a terminal state, either successful or unsuccessful.
53+
NEXUS_OPERATION_WAIT_STAGE_CLOSED = 2;
54+
}
55+
56+
// Defines whether to allow re-using an operation ID from a previously *closed* Nexus operation.
57+
// If the request is denied, the server returns a `NexusOperationAlreadyStarted` error.
58+
//
59+
// See `NexusOperationIdConflictPolicy` for handling ID duplication with a *running* operation.
60+
enum NexusOperationIdReusePolicy {
61+
NEXUS_OPERATION_ID_REUSE_POLICY_UNSPECIFIED = 0;
62+
// Always allow starting an operation using the same operation ID.
63+
NEXUS_OPERATION_ID_REUSE_POLICY_ALLOW_DUPLICATE = 1;
64+
// Allow starting an operation using the same ID only when the last operation's final state is one
65+
// of {failed, canceled, terminated, timed out}.
66+
NEXUS_OPERATION_ID_REUSE_POLICY_ALLOW_DUPLICATE_FAILED_ONLY = 2;
67+
// Do not permit re-use of the ID for this operation. Future start requests could potentially change the policy,
68+
// allowing re-use of the ID.
69+
NEXUS_OPERATION_ID_REUSE_POLICY_REJECT_DUPLICATE = 3;
70+
}
71+
72+
// Defines what to do when trying to start a Nexus operation with the same ID as a *running* operation.
73+
// Note that it is *never* valid to have two running instances of the same operation ID.
74+
//
75+
// See `NexusOperationIdReusePolicy` for handling operation ID duplication with a *closed* operation.
76+
enum NexusOperationIdConflictPolicy {
77+
NEXUS_OPERATION_ID_CONFLICT_POLICY_UNSPECIFIED = 0;
78+
// Don't start a new operation; instead return `NexusOperationAlreadyStarted` error.
79+
NEXUS_OPERATION_ID_CONFLICT_POLICY_FAIL = 1;
80+
// Don't start a new operation; instead return a handle for the running operation.
81+
NEXUS_OPERATION_ID_CONFLICT_POLICY_USE_EXISTING = 2;
82+
}

temporal/api/errordetails/v1/message.proto

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,11 @@ message ActivityExecutionAlreadyStartedFailure {
129129
string start_request_id = 1;
130130
string run_id = 2;
131131
}
132+
133+
// An error indicating that a Nexus operation failed to start. Returned when there is an existing operation with the
134+
// given operation ID, and the given ID reuse and conflict policies do not permit starting a new one or attaching to an
135+
// existing one.
136+
message NexusOperationExecutionAlreadyStartedFailure {
137+
string start_request_id = 1;
138+
string run_id = 2;
139+
}

temporal/api/nexus/v1/message.proto

Lines changed: 151 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@ option java_outer_classname = "MessageProto";
99
option ruby_package = "Temporalio::Api::Nexus::V1";
1010
option csharp_namespace = "Temporalio.Api.Nexus.V1";
1111

12+
import "google/protobuf/duration.proto";
1213
import "google/protobuf/timestamp.proto";
1314
import "temporal/api/common/v1/message.proto";
15+
import "temporal/api/enums/v1/common.proto";
1416
import "temporal/api/enums/v1/nexus.proto";
1517
import "temporal/api/failure/v1/message.proto";
18+
import "temporal/api/sdk/v1/user_metadata.proto";
1619

1720
// A general purpose failure message.
1821
// See: https://github.com/nexus-rpc/api/blob/main/SPEC.md#failure
@@ -199,7 +202,7 @@ message EndpointTarget {
199202
// Nexus task queue to route requests to.
200203
string task_queue = 2;
201204
}
202-
205+
203206
// Target an external server by URL.
204207
// At a later point, this will support providing credentials, in the meantime, an http.RoundTripper can be injected
205208
// into the server to modify the request.
@@ -213,3 +216,150 @@ message EndpointTarget {
213216
External external = 2;
214217
}
215218
}
219+
220+
// NexusOperationExecutionCancellationInfo contains the state of a Nexus operation cancellation.
221+
message NexusOperationExecutionCancellationInfo {
222+
// The time when cancellation was requested.
223+
google.protobuf.Timestamp requested_time = 1;
224+
225+
temporal.api.enums.v1.NexusOperationCancellationState state = 2;
226+
227+
// The number of attempts made to deliver the cancel operation request.
228+
// This number represents a minimum bound since the attempt is incremented after the request completes.
229+
int32 attempt = 3;
230+
231+
// The time when the last attempt completed.
232+
google.protobuf.Timestamp last_attempt_complete_time = 4;
233+
// The last attempt's failure, if any.
234+
temporal.api.failure.v1.Failure last_attempt_failure = 5;
235+
// The time when the next attempt is scheduled.
236+
google.protobuf.Timestamp next_attempt_schedule_time = 6;
237+
238+
// If the state is BLOCKED, blocked reason provides additional information.
239+
string blocked_reason = 7;
240+
241+
// A reason that may be specified in the CancelNexusOperationRequest.
242+
string reason = 8;
243+
}
244+
245+
// Full current state of a standalone Nexus operation, as of the time of the request.
246+
message NexusOperationExecutionInfo {
247+
// Unique identifier of this Nexus operation within its namespace along with run ID (below).
248+
string operation_id = 1;
249+
string run_id = 2;
250+
251+
// Endpoint name, resolved to a URL via the cluster's endpoint registry.
252+
string endpoint = 3;
253+
// Service name.
254+
string service = 4;
255+
// Operation name.
256+
string operation = 5;
257+
258+
// A general status for this operation, indicates whether it is currently running or in one of the terminal statuses.
259+
// Updated once when the operation is originally scheduled, and again when it reaches a terminal status.
260+
temporal.api.enums.v1.NexusOperationExecutionStatus status = 6;
261+
// More detailed breakdown of NEXUS_OPERATION_EXECUTION_STATUS_RUNNING.
262+
temporal.api.enums.v1.PendingNexusOperationState state = 7;
263+
264+
// Schedule-to-close timeout for this operation.
265+
// (-- api-linter: core::0140::prepositions=disabled
266+
// aip.dev/not-precedent: "to" is used to indicate interval. --)
267+
google.protobuf.Duration schedule_to_close_timeout = 8;
268+
269+
// Schedule-to-start timeout for this operation.
270+
// (-- api-linter: core::0140::prepositions=disabled
271+
// aip.dev/not-precedent: "to" is used to indicate interval. --)
272+
google.protobuf.Duration schedule_to_start_timeout = 9;
273+
274+
// Start-to-close timeout for this operation.
275+
// (-- api-linter: core::0140::prepositions=disabled
276+
// aip.dev/not-precedent: "to" is used to indicate interval. --)
277+
google.protobuf.Duration start_to_close_timeout = 10;
278+
279+
// The number of attempts made to deliver the start operation request.
280+
// This number is approximate, it is incremented when a task is added to the history queue.
281+
// In practice, there could be more attempts if a task is executed but fails to commit, or less attempts if a task
282+
// was never executed.
283+
int32 attempt = 11;
284+
285+
// Time the operation was originally scheduled via a StartNexusOperation request.
286+
google.protobuf.Timestamp schedule_time = 12;
287+
// Scheduled time + schedule to close timeout.
288+
google.protobuf.Timestamp expiration_time = 13;
289+
// Time when the operation transitioned to a closed state.
290+
google.protobuf.Timestamp close_time = 14;
291+
292+
// The time when the last attempt completed.
293+
google.protobuf.Timestamp last_attempt_complete_time = 15;
294+
// The last attempt's failure, if any.
295+
temporal.api.failure.v1.Failure last_attempt_failure = 16;
296+
// The time when the next attempt is scheduled.
297+
google.protobuf.Timestamp next_attempt_schedule_time = 17;
298+
299+
// Elapsed time from schedule_time to now for running operations or to close_time for closed
300+
// operations, including all attempts and backoff between attempts.
301+
google.protobuf.Duration execution_duration = 18;
302+
303+
NexusOperationExecutionCancellationInfo cancellation_info = 19;
304+
305+
// If the state is BLOCKED, blocked reason provides additional information.
306+
string blocked_reason = 20;
307+
308+
// Server-generated request ID used as an idempotency token when submitting start requests to
309+
// the handler. Distinct from the request_id in StartNexusOperationRequest, which is the
310+
// caller-side idempotency key for the StartNexusOperation RPC itself.
311+
string request_id = 21;
312+
313+
// Operation token. Only set for asynchronous operations after a successful StartOperation call.
314+
string operation_token = 22;
315+
316+
// Incremented each time the operation's state is mutated in persistence.
317+
int64 state_transition_count = 23;
318+
319+
temporal.api.common.v1.SearchAttributes search_attributes = 24;
320+
321+
// Header for context propagation and tracing purposes.
322+
map<string, string> nexus_header = 25;
323+
324+
// Metadata for use by user interfaces to display the fixed as-of-start summary and details of the operation.
325+
temporal.api.sdk.v1.UserMetadata user_metadata = 26;
326+
327+
// Links attached by the handler of this operation on start or completion.
328+
repeated temporal.api.common.v1.Link links = 27;
329+
330+
// The identity of the client who started this operation.
331+
string identity = 28;
332+
}
333+
334+
// Limited Nexus operation information returned in the list response.
335+
// When adding fields here, ensure that it is also present in NexusOperationExecutionInfo (note that it may already be present in
336+
// NexusOperationExecutionInfo but not at the top-level).
337+
message NexusOperationExecutionListInfo {
338+
// A unique identifier of this operation within its namespace along with run ID (below).
339+
string operation_id = 1;
340+
// The run ID of the standalone Nexus operation.
341+
string run_id = 2;
342+
343+
// Endpoint name.
344+
string endpoint = 3;
345+
// Service name.
346+
string service = 4;
347+
// Operation name.
348+
string operation = 5;
349+
350+
// Time the operation was originally scheduled via a StartNexusOperation request.
351+
google.protobuf.Timestamp schedule_time = 6;
352+
// If the operation is in a terminal status, this field represents the time the operation transitioned to that status.
353+
google.protobuf.Timestamp close_time = 7;
354+
// The status is updated once, when the operation is originally scheduled, and again when the operation reaches a terminal status.
355+
temporal.api.enums.v1.NexusOperationExecutionStatus status = 8;
356+
357+
// Search attributes from the start request.
358+
temporal.api.common.v1.SearchAttributes search_attributes = 9;
359+
360+
// Updated on terminal status.
361+
int64 state_transition_count = 10;
362+
// The difference between close time and scheduled time.
363+
// This field is only populated if the operation is closed.
364+
google.protobuf.Duration execution_duration = 11;
365+
}

temporal/api/workflow/v1/message.proto

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,9 @@ message PendingNexusOperationInfo {
515515
temporal.api.enums.v1.PendingNexusOperationState state = 7;
516516

517517
// The number of attempts made to deliver the start operation request.
518-
// This number represents a minimum bound since the attempt is incremented after the request completes.
518+
// This number is approximate, it is incremented when a task is added to the history queue.
519+
// In practice, there could be more attempts if a task is executed but fails to commit, or less attempts if a task
520+
// was never executed.
519521
int32 attempt = 8;
520522

521523
// The time when the last attempt completed.
@@ -753,4 +755,3 @@ message WorkflowExecutionPauseInfo {
753755
// The reason for pausing the workflow execution.
754756
string reason = 3;
755757
}
756-

0 commit comments

Comments
 (0)