Skip to content

Commit 6343d13

Browse files
committed
Add standalone activity APIs
Missing API support for: - [ ] PauseActivity - [ ] UnpauseActivity - [ ] ResetActivity - [ ] UpdateActivityOptions
1 parent a09b22e commit 6343d13

File tree

8 files changed

+3283
-488
lines changed

8 files changed

+3283
-488
lines changed

openapi/openapiv2.json

Lines changed: 1620 additions & 438 deletions
Large diffs are not rendered by default.

openapi/openapiv3.yaml

Lines changed: 1135 additions & 42 deletions
Large diffs are not rendered by default.

temporal/api/activity/v1/message.proto

Lines changed: 165 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,36 @@ option java_outer_classname = "MessageProto";
99
option ruby_package = "Temporalio::Api::Activity::V1";
1010
option csharp_namespace = "Temporalio.Api.Activity.V1";
1111

12+
import "google/protobuf/duration.proto";
13+
import "google/protobuf/timestamp.proto";
14+
1215
import "temporal/api/common/v1/message.proto";
16+
import "temporal/api/deployment/v1/message.proto";
17+
import "temporal/api/enums/v1/activity.proto";
18+
import "temporal/api/enums/v1/workflow.proto";
19+
import "temporal/api/failure/v1/message.proto";
1320
import "temporal/api/taskqueue/v1/message.proto";
21+
import "temporal/api/sdk/v1/user_metadata.proto";
1422

15-
import "google/protobuf/duration.proto";
23+
// Identifies a specific activity within a namespace. Practically speaking, because run_id is a
24+
// uuid, a workflow execution is globally unique. Note that many commands allow specifying an empty
25+
// run id as a way of saying "target the latest run of the activity".
26+
// TODO: Make this a generic EntityExecution?
27+
message ActivityExecution {
28+
string activity_id = 1;
29+
string run_id = 2;
30+
}
31+
32+
// When StartActivityExecution uses the ID_CONFLICT_POLICY_USE_EXISTING and there is already an existing running
33+
// activity, OnConflictOptions defines actions to be taken on the existing running activity, updating its state.
34+
message OnConflictOptions {
35+
// Attaches the request ID to the running workflow.
36+
bool attach_request_id = 1;
37+
// Attaches the completion callbacks to the running workflow.
38+
bool attach_completion_callbacks = 2;
39+
// Attaches the links to the WorkflowExecutionOptionsUpdatedEvent history event.
40+
bool attach_links = 3;
41+
}
1642

1743
message ActivityOptions {
1844
temporal.api.taskqueue.v1.TaskQueue task_queue = 1;
@@ -40,6 +66,142 @@ message ActivityOptions {
4066
google.protobuf.Duration start_to_close_timeout = 4;
4167
// Maximum permitted time between successful worker heartbeats.
4268
google.protobuf.Duration heartbeat_timeout = 5;
43-
69+
// The retry policy for the activity. Will never exceed `schedule_to_close_timeout`.
4470
temporal.api.common.v1.RetryPolicy retry_policy = 6;
45-
}
71+
}
72+
73+
// Info for a standalone activity.
74+
message ActivityExecutionInfo {
75+
// Unique identifier of this activity within its namespace.
76+
ActivityExecution activity_execution = 1;
77+
78+
// The type of the activity, a string that maps to a registered activity on a worker.
79+
temporal.api.common.v1.ActivityType activity_type = 2;
80+
// A general status for this activity, indicates whether it is currently running or in one of the terminal statuses.
81+
temporal.api.enums.v1.ActivityExecutionStatus status = 3;
82+
// More detailed breakdown of ACTIVITY_EXECUTION_STATUS_RUNNING.
83+
temporal.api.enums.v1.PendingActivityState run_state = 4;
84+
// Details provided in the last recorded activity heartbeat.
85+
temporal.api.common.v1.Payloads heartbeat_details = 5;
86+
// Time the last heartbeat was recorded.
87+
google.protobuf.Timestamp last_heartbeat_time = 6;
88+
// Time the last attempt was started.
89+
google.protobuf.Timestamp last_started_time = 7;
90+
// The attempt this activity is currently on.
91+
// Incremented each time a new attempt is started.
92+
// TODO: Confirm if this is on scheduled or started.
93+
int32 attempt = 8;
94+
int32 maximum_attempts = 9;
95+
// Time the activity was originally scheduled via a StartActivityExecution request.
96+
google.protobuf.Timestamp scheduled_time = 10;
97+
// Scheduled time + schedule to close timeout.
98+
google.protobuf.Timestamp expiration_time = 11;
99+
// Failure details from the last failed attempt.
100+
temporal.api.failure.v1.Failure last_failure = 12;
101+
string last_worker_identity = 13;
102+
103+
// Time until the next activity retry.
104+
// If the activity is currently running, this represents the next retry interval in case the attempt fails.
105+
// If activity is currently backing off between attempt, this represents the current retry interval.
106+
// If there is no next retry allowed, this field will be null.
107+
// This interval is typically calculated from the specified retry policy, but may be modified if an activity fails
108+
// with a retryable application failure specifying a retry delay.
109+
google.protobuf.Duration current_retry_interval = 16;
110+
111+
// The time when the last activity attempt completed. If activity has not been completed yet, it will be null.
112+
google.protobuf.Timestamp last_attempt_complete_time = 17;
113+
114+
// The time when the next activity attempt will be scheduled.
115+
// If activity is currently scheduled or started, this field will be null.
116+
google.protobuf.Timestamp next_attempt_schedule_time = 18;
117+
118+
// Indicates if the activity is paused.
119+
// TODO: We already have this information in PendingActivityState, do we need to duplicate it here?
120+
// TODO: Clarify if this is also true when the activity is in PAUSE_REQUESTED state.
121+
bool paused = 19;
122+
123+
// The Worker Deployment Version this activity was dispatched to most recently.
124+
// If nil, the activity has not yet been dispatched or was last dispatched to an unversioned worker.
125+
temporal.api.deployment.v1.WorkerDeploymentVersion last_deployment_version = 20;
126+
127+
// Priority metadata.
128+
temporal.api.common.v1.Priority priority = 21;
129+
130+
// TODO: Move this to a common package?
131+
message PauseInfo {
132+
// The time when the activity was paused.
133+
google.protobuf.Timestamp pause_time = 1;
134+
135+
message Manual {
136+
// The identity of the actor that paused the activity.
137+
string identity = 1;
138+
// Reason for pausing the activity.
139+
string reason = 2;
140+
}
141+
142+
oneof paused_by {
143+
// The activity was paused by direct API invocation.
144+
Manual manual = 2;
145+
}
146+
}
147+
148+
PauseInfo pause_info = 22;
149+
150+
// Current activity options. May be different from the one used to start the activity.
151+
temporal.api.activity.v1.ActivityOptions activity_options = 23;
152+
153+
// Serialized activity input, passed as arguments to the activity function.
154+
temporal.api.common.v1.Payloads input = 24;
155+
156+
// Incremented each time the activity's state is mutated in persistence.
157+
int64 state_transition_count = 25;
158+
159+
temporal.api.common.v1.SearchAttributes search_attributes = 26;
160+
temporal.api.common.v1.Header header = 27;
161+
// Whether the activity was started with a request_eager_execution flag set to `true`, indicating that the first
162+
// task was delivered inline in the start response, bypassing matching.
163+
bool eager_execution_requested = 28;
164+
165+
// Callbacks to be called by the server when this activity reaches a terminal status.
166+
// Callback addresses must be whitelisted in the server's dynamic configuration.
167+
repeated temporal.api.common.v1.Callback completion_callbacks = 29;
168+
// Metadata for use by user interfaces to display the fixed as-of-start summary and details of the activity.
169+
temporal.api.sdk.v1.UserMetadata user_metadata = 30;
170+
// Links to be associated with the activity.
171+
repeated temporal.api.common.v1.Link links = 31;
172+
173+
// Set if activity cancelation was requested.
174+
string canceled_reason = 32;
175+
}
176+
177+
// Limited activity information returned in the list response.
178+
message ActivityListInfo {
179+
// Unique identifier of this activity within its namespace.
180+
ActivityExecution activity_execution = 1;
181+
// The type of the activity, a string that maps to a registered activity on a worker.
182+
temporal.api.common.v1.ActivityType activity_type = 2;
183+
// Time the activity was originally scheduled via a StartActivityExecution request.
184+
// TODO: Workflows call this schedule_time but it's scheduled_time in PendingActivityInfo, what should we choose for
185+
// consistency?
186+
google.protobuf.Timestamp scheduled_time = 3;
187+
// If the activity is in a terminal status, this field represents the time the activity transitioned to that status.
188+
google.protobuf.Timestamp close_time = 4;
189+
// Only scheduled and terminal statuses appear here. More detailed information in PendingActivityInfo but not
190+
// available in the list response.
191+
temporal.api.enums.v1.ActivityExecutionStatus status = 5;
192+
193+
// Memo from the start request.
194+
temporal.api.common.v1.Memo memo = 6;
195+
// Search attributes from the start request.
196+
temporal.api.common.v1.SearchAttributes search_attributes = 7;
197+
198+
// The task queue this activity was scheduled on when it was originally started, updated on activity options update.
199+
string task_queue = 8;
200+
// Updated on terminal status.
201+
int64 state_transition_count = 9;
202+
// Updated once on scheduled and once on terminal status.
203+
int64 state_size_bytes = 10;
204+
// The difference between close time and scheduled time.
205+
// This field is only populated if the activity is closed.
206+
google.protobuf.Duration execution_duration = 11;
207+
}

temporal/api/common/v1/message.proto

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,17 @@ message Link {
232232
string job_id = 1;
233233
}
234234

235+
// A link to an activity.
236+
message Activity {
237+
string namespace = 1;
238+
string activity_id = 2;
239+
string run_id = 3;
240+
}
241+
235242
oneof variant {
236243
WorkflowEvent workflow_event = 1;
237244
BatchJob batch_job = 2;
245+
Activity activity = 3;
238246
}
239247
}
240248

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
syntax = "proto3";
2+
3+
package temporal.api.enums.v1;
4+
5+
option go_package = "go.temporal.io/api/enums/v1;enums";
6+
option java_package = "io.temporal.api.enums.v1";
7+
option java_multiple_files = true;
8+
option java_outer_classname = "ActivityProto";
9+
option ruby_package = "Temporalio::Api::Enums::V1";
10+
option csharp_namespace = "Temporalio.Api.Enums.V1";
11+
12+
// Status of a standalone activity.
13+
// The status is updated once, when the activity is originally scheduled, and again when the activity reaches a terminal
14+
// status.
15+
// TODO: Should this be a common execution status? Seems like the other archetypes will share this status.
16+
// (-- api-linter: core::0216::synonyms=disabled
17+
// aip.dev/not-precedent: Named consistently with WorkflowExecutionStatus. --)
18+
enum ActivityExecutionStatus {
19+
ACTIVITY_EXECUTION_STATUS_UNSPECIFIED = 0;
20+
// The activity is not in a terminal status. This does not necessarily mean that there is a currently running
21+
// attempt. The activity may be backing off between attempts or waiting for a worker to pick it up.
22+
ACTIVITY_EXECUTION_STATUS_RUNNING = 1;
23+
// The activity completed successfully.
24+
ACTIVITY_EXECUTION_STATUS_COMPLETED = 2;
25+
// The activity completed with failure.
26+
ACTIVITY_EXECUTION_STATUS_FAILED = 3;
27+
// The activity completed as canceled.
28+
// Requesting to cancel an activity does not automatically transition the activity to canceled status. If the
29+
// activity has a currently running attempt, the activity will only transition to canceled status if the current
30+
// attempt is unsuccessful.
31+
// TODO: Clarify what happens if there are no more allowed retries after the current attempt.
32+
ACTIVITY_EXECUTION_STATUS_CANCELED = 4;
33+
// The activity was terminated. Termination does not reach the worker and the activity code cannot react to it.
34+
// A terminated activity may have a running attempt and will be requested to be canceled by the server when it
35+
// heartbeats.
36+
ACTIVITY_EXECUTION_STATUS_TERMINATED = 5;
37+
// The activity has timed out by reaching the specified shedule-to-start or schedule-to-close timeouts.
38+
// TODO: Clarify if there are other conditions where the activity can end up in timed out status.
39+
ACTIVITY_EXECUTION_STATUS_TIMED_OUT = 6;
40+
}

temporal/api/enums/v1/id.proto

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
syntax = "proto3";
2+
3+
package temporal.api.enums.v1;
4+
5+
option go_package = "go.temporal.io/api/enums/v1;enums";
6+
option java_package = "io.temporal.api.enums.v1";
7+
option java_multiple_files = true;
8+
option java_outer_classname = "IdProto";
9+
option ruby_package = "Temporalio::Api::Enums::V1";
10+
option csharp_namespace = "Temporalio.Api.Enums.V1";
11+
12+
// Defines whether to allow re-using an ID from a previously *closed* execution.
13+
// If the request is denied, the server returns an `ExecutionAlreadyStarted` error.
14+
//
15+
// See `IdConflictPolicy` for handling ID duplication with a *running* execution.
16+
enum IdReusePolicy {
17+
ID_REUSE_POLICY_UNSPECIFIED = 0;
18+
// Always allow starting an execution using the same entity ID.
19+
ID_REUSE_POLICY_ALLOW_DUPLICATE = 1;
20+
// Allow starting an execution using the same ID, only when the last execution's final state is one of [terminated,
21+
// cancelled, timed out, failed].
22+
ID_REUSE_POLICY_ALLOW_DUPLICATE_FAILED_ONLY = 2;
23+
// Do not permit re-use of the ID for this execution. Future start requests could potentially change the policy,
24+
// allowing re-use of the ID.
25+
ID_REUSE_POLICY_REJECT_DUPLICATE = 3;
26+
}
27+
28+
// Defines what to do when trying to start an execution with the same ID as a *running* execution.
29+
// Note that it is *never* valid to have two actively running instances of the same execution ID.
30+
//
31+
// See `IdReusePolicy` for handling execution ID duplication with a *closed* execution.
32+
enum IdConflictPolicy {
33+
ID_CONFLICT_POLICY_UNSPECIFIED = 0;
34+
// Don't start a new execution; instead return `ExecutionAlreadyStarted` error.
35+
ID_CONFLICT_POLICY_FAIL = 1;
36+
// Don't start a new execution; instead return a handle for the running execution.
37+
ID_CONFLICT_POLICY_USE_EXISTING = 2;
38+
// Terminate the running execution before starting a new one.
39+
ID_CONFLICT_POLICY_TERMINATE_EXISTING = 3;
40+
}

0 commit comments

Comments
 (0)