Skip to content

Commit 0c3209c

Browse files
Add Stand Alone Callbacks
1 parent 43e4896 commit 0c3209c

File tree

9 files changed

+2048
-54
lines changed

9 files changed

+2048
-54
lines changed

openapi/openapiv2.json

Lines changed: 893 additions & 20 deletions
Large diffs are not rendered by default.

openapi/openapiv3.yaml

Lines changed: 806 additions & 34 deletions
Large diffs are not rendered by default.
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
syntax = "proto3";
2+
3+
package temporal.api.callback.v1;
4+
5+
option go_package = "go.temporal.io/api/callback/v1;callback";
6+
option java_package = "io.temporal.api.callback.v1";
7+
option java_multiple_files = true;
8+
option java_outer_classname = "MessageProto";
9+
option ruby_package = "Temporalio::Api::Callback::V1";
10+
option csharp_namespace = "Temporalio.Api.Callback.V1";
11+
12+
import "google/protobuf/duration.proto";
13+
import "google/protobuf/empty.proto";
14+
import "google/protobuf/timestamp.proto";
15+
16+
import "temporal/api/common/v1/message.proto";
17+
import "temporal/api/enums/v1/common.proto";
18+
import "temporal/api/failure/v1/message.proto";
19+
20+
// The outcome of a completed callback execution: either success or a failure.
21+
message CallbackExecutionOutcome {
22+
oneof value {
23+
// The callback completed successfully.
24+
google.protobuf.Empty success = 1;
25+
// The failure if the callback completed unsuccessfully.
26+
temporal.api.failure.v1.Failure failure = 2;
27+
}
28+
}
29+
30+
// The Nexus completion data that a standalone callback execution will deliver to its target URL.
31+
// Exactly one of success or failure should be set.
32+
message CallbackExecutionCompletion {
33+
oneof result {
34+
// Deliver a successful Nexus operation completion with this result payload.
35+
// If set, the callback delivers a successful completion to the target URL.
36+
temporal.api.common.v1.Payload success = 1;
37+
// Deliver a failed Nexus operation completion with this failure.
38+
// If set, the callback delivers a failed completion to the target URL.
39+
temporal.api.failure.v1.Failure failure = 2;
40+
}
41+
}
42+
43+
// Information about a standalone callback execution.
44+
message CallbackExecutionInfo {
45+
// Unique identifier of this callback within its namespace.
46+
string callback_id = 1;
47+
48+
// Run ID of the callback execution.
49+
string run_id = 2;
50+
51+
// Information on how this callback should be invoked (e.g. its URL and type).
52+
temporal.api.common.v1.Callback callback = 3;
53+
54+
// Current state of the callback.
55+
temporal.api.enums.v1.CallbackState state = 4;
56+
57+
// The number of attempts made to deliver the callback.
58+
// This number represents a minimum bound since the attempt is incremented after the callback request completes.
59+
int32 attempt = 5;
60+
61+
// The time when the callback was created/scheduled.
62+
google.protobuf.Timestamp create_time = 6;
63+
64+
// The time when the last attempt completed.
65+
google.protobuf.Timestamp last_attempt_complete_time = 7;
66+
67+
// The last attempt's failure, if any.
68+
temporal.api.failure.v1.Failure last_attempt_failure = 8;
69+
70+
// The time when the next attempt is scheduled.
71+
google.protobuf.Timestamp next_attempt_schedule_time = 9;
72+
73+
// If the state is BLOCKED, provides additional information.
74+
string blocked_reason = 10;
75+
76+
// Time when the callback transitioned to a terminal state.
77+
google.protobuf.Timestamp close_time = 11;
78+
79+
// Search attributes for indexing.
80+
temporal.api.common.v1.SearchAttributes search_attributes = 12;
81+
82+
// Schedule-to-close timeout for this callback.
83+
// (-- api-linter: core::0140::prepositions=disabled
84+
// aip.dev/not-precedent: "to" is used to indicate interval. --)
85+
google.protobuf.Duration schedule_to_close_timeout = 13;
86+
87+
// Incremented each time the callback's state is mutated in persistence.
88+
int64 state_transition_count = 14;
89+
}
90+
91+
// Limited callback information returned in the list response.
92+
message CallbackExecutionListInfo {
93+
// Unique identifier of this callback within its namespace.
94+
string callback_id = 1;
95+
96+
// Run ID of the callback execution.
97+
string run_id = 2;
98+
99+
// Current state of the callback.
100+
temporal.api.enums.v1.CallbackState state = 3;
101+
102+
// The time when the callback was created/scheduled.
103+
google.protobuf.Timestamp create_time = 4;
104+
105+
// Time when the callback transitioned to a terminal state.
106+
google.protobuf.Timestamp close_time = 5;
107+
108+
// Search attributes from the start request.
109+
temporal.api.common.v1.SearchAttributes search_attributes = 6;
110+
111+
// Incremented each time the callback's state is mutated.
112+
int64 state_transition_count = 7;
113+
}

temporal/api/common/v1/message.proto

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ message Callback {
181181
string url = 1;
182182
// Header to attach to callback request.
183183
map<string, string> header = 2;
184+
// Standard token to use for completion.
185+
string token = 3;
184186
}
185187

186188
// Callbacks to be delivered internally within the system.
@@ -240,9 +242,15 @@ message Link {
240242
string job_id = 1;
241243
}
242244

245+
// A link to a durable callback execution
246+
message CallbackExecution {
247+
string callback_id = 1;
248+
}
249+
243250
oneof variant {
244251
WorkflowEvent workflow_event = 1;
245252
BatchJob batch_job = 2;
253+
CallbackExecution callback_execution = 3;
246254
}
247255
}
248256

temporal/api/enums/v1/common.proto

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ enum CallbackState {
4949
CALLBACK_STATE_SUCCEEDED = 5;
5050
// Callback is blocked (eg: by circuit breaker).
5151
CALLBACK_STATE_BLOCKED = 6;
52+
// Callback was canceled via RequestCancelCallbackExecution.
53+
CALLBACK_STATE_CANCELED = 7;
54+
// Callback was terminated via TerminateCallbackExecution.
55+
CALLBACK_STATE_TERMINATED = 8;
5256
}
5357

5458
// State of a pending Nexus operation.

temporal/api/errordetails/v1/message.proto

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,9 @@ message ActivityExecutionAlreadyStartedFailure {
129129
string start_request_id = 1;
130130
string run_id = 2;
131131
}
132+
133+
// An error indicating that a callback execution failed to start because a callback with the given
134+
// callback ID already exists in this namespace.
135+
message CallbackExecutionAlreadyStartedFailure {
136+
string start_request_id = 1;
137+
}

temporal/api/nexus/v1/message.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ message StartOperationRequest {
6161
map<string, string> callback_header = 6;
6262
// Links contain caller information and can be attached to the operations started by the handler.
6363
repeated Link links = 7;
64+
// Callback token
65+
string callback_token = 8;
6466
}
6567

6668
// A request to cancel an operation.

temporal/api/workflowservice/v1/request_response.proto

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import "temporal/api/enums/v1/deployment.proto";
2121
import "temporal/api/enums/v1/update.proto";
2222
import "temporal/api/enums/v1/activity.proto";
2323
import "temporal/api/activity/v1/message.proto";
24+
import "temporal/api/callback/v1/message.proto";
2425
import "temporal/api/common/v1/message.proto";
2526
import "temporal/api/history/v1/message.proto";
2627
import "temporal/api/workflow/v1/message.proto";
@@ -2956,3 +2957,137 @@ message DeleteActivityExecutionRequest {
29562957

29572958
message DeleteActivityExecutionResponse {
29582959
}
2960+
2961+
message StartCallbackExecutionRequest {
2962+
string namespace = 1;
2963+
// The identity of the client who initiated this request.
2964+
string identity = 2;
2965+
// A unique identifier for this start request. Typically UUIDv4.
2966+
string request_id = 3;
2967+
// Identifier for this callback. Required. Must be unique among callbacks in the same namespace.
2968+
// If a callback with this ID already exists, the request will fail with CallbackExecutionAlreadyStarted.
2969+
string callback_id = 4;
2970+
// Callback execution run ID, targets the latest run if run_id is empty.
2971+
string run_id = 5;
2972+
// Information on how this callback should be invoked (e.g. its URL and type).
2973+
temporal.api.common.v1.Callback callback = 6;
2974+
// Schedule-to-close timeout for this callback.
2975+
// (-- api-linter: core::0140::prepositions=disabled
2976+
// aip.dev/not-precedent: "to" is used to indicate interval. --)
2977+
google.protobuf.Duration schedule_to_close_timeout = 7;
2978+
// Search attributes for indexing.
2979+
temporal.api.common.v1.SearchAttributes search_attributes = 8;
2980+
// The Nexus completion data to deliver to the callback URL.
2981+
// Required. Contains either a successful result payload or a failure.
2982+
temporal.api.callback.v1.CallbackExecutionCompletion completion = 9;
2983+
}
2984+
2985+
message StartCallbackExecutionResponse {
2986+
// The run ID of the callback that was started.
2987+
string run_id = 1;
2988+
}
2989+
2990+
message DescribeCallbackExecutionRequest {
2991+
string namespace = 1;
2992+
// Identifier for the callback
2993+
string callback_id = 2;
2994+
// Run ID of the callback execution to describe. If empty, the latest run will be described.
2995+
string run_id = 3;
2996+
// Include the outcome (result/failure) in the response if the callback has completed.
2997+
bool include_outcome = 4;
2998+
// Token from a previous DescribeCallbackExecutionResponse. If present, long-poll until callback
2999+
// state changes from the state encoded in this token. If absent, return current state immediately.
3000+
// Note that callback state may change multiple times between requests, therefore it is not
3001+
// guaranteed that a client making a sequence of long-poll requests will see a complete
3002+
// sequence of state changes.
3003+
bytes long_poll_token = 5;
3004+
}
3005+
3006+
message DescribeCallbackExecutionResponse {
3007+
// Information about the callback execution.
3008+
temporal.api.callback.v1.CallbackExecutionInfo info = 1;
3009+
// Only set if the callback is completed and include_outcome was true in the request.
3010+
temporal.api.callback.v1.CallbackExecutionOutcome outcome = 2;
3011+
// Token for follow-on long-poll requests. Absent only if the callback is complete.
3012+
bytes long_poll_token = 3;
3013+
}
3014+
3015+
message PollCallbackExecutionRequest {
3016+
string namespace = 1;
3017+
// Identifier for the callback
3018+
string callback_id = 2;
3019+
// Run ID of the callback execution to poll. If empty, the latest run will be polled.
3020+
string run_id = 3;
3021+
}
3022+
3023+
message PollCallbackExecutionResponse {
3024+
temporal.api.callback.v1.CallbackExecutionOutcome outcome = 1;
3025+
}
3026+
3027+
message ListCallbackExecutionsRequest {
3028+
string namespace = 1;
3029+
// Max number of executions to return per page.
3030+
int32 page_size = 2;
3031+
// Token returned in ListCallbackExecutionsResponse.
3032+
bytes next_page_token = 3;
3033+
// Visibility query, see https://docs.temporal.io/list-filter for the syntax.
3034+
string query = 4;
3035+
}
3036+
3037+
message ListCallbackExecutionsResponse {
3038+
repeated temporal.api.callback.v1.CallbackExecutionListInfo executions = 1;
3039+
// Token to use to fetch the next page. If empty, there is no next page.
3040+
bytes next_page_token = 2;
3041+
}
3042+
3043+
message CountCallbackExecutionsRequest {
3044+
string namespace = 1;
3045+
// Visibility query, see https://docs.temporal.io/list-filter for the syntax.
3046+
string query = 2;
3047+
}
3048+
3049+
message CountCallbackExecutionsResponse {
3050+
// If `query` is not grouping by any field, the count is an approximate number
3051+
// of callbacks that match the query.
3052+
// If `query` is grouping by a field, the count is simply the sum of the counts
3053+
// of the groups returned in the response. This number can be smaller than the
3054+
// total number of callbacks matching the query.
3055+
int64 count = 1;
3056+
3057+
// Contains the groups if the request is grouping by a field.
3058+
// The list might not be complete, and the counts of each group is approximate.
3059+
repeated AggregationGroup groups = 2;
3060+
3061+
message AggregationGroup {
3062+
repeated temporal.api.common.v1.Payload group_values = 1;
3063+
int64 count = 2;
3064+
}
3065+
}
3066+
3067+
message TerminateCallbackExecutionRequest {
3068+
string namespace = 1;
3069+
// Identifier for the callback
3070+
string callback_id = 2;
3071+
// Run ID of the callback execution to terminate. If empty, the latest run will be terminated.
3072+
string run_id = 3;
3073+
// The identity of the worker/client.
3074+
string identity = 4;
3075+
// Used to de-dupe termination requests.
3076+
string request_id = 5;
3077+
// Reason for requesting the termination.
3078+
string reason = 6;
3079+
}
3080+
3081+
message TerminateCallbackExecutionResponse {
3082+
}
3083+
3084+
message DeleteCallbackExecutionRequest {
3085+
string namespace = 1;
3086+
// Identifier for the callback
3087+
string callback_id = 2;
3088+
// Run ID of the callback execution to delete. If empty, the latest run will be deleted.
3089+
string run_id = 3;
3090+
}
3091+
3092+
message DeleteCallbackExecutionResponse {
3093+
}

0 commit comments

Comments
 (0)