Skip to content

Commit 1a1e74e

Browse files
dandavisonbergundyfretz12
authored
Standalone Activity (#688)
Standalone Activity API --------- Co-authored-by: Roey Berman <[email protected]> Co-authored-by: Fred Tzeng <[email protected]>
1 parent 50957d1 commit 1a1e74e

File tree

8 files changed

+3725
-933
lines changed

8 files changed

+3725
-933
lines changed

openapi/openapiv2.json

Lines changed: 2004 additions & 861 deletions
Large diffs are not rendered by default.

openapi/openapiv3.yaml

Lines changed: 1141 additions & 52 deletions
Large diffs are not rendered by default.

temporal/api/activity/v1/message.proto

Lines changed: 151 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,26 @@ 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+
// The outcome of a completed activity execution: either a successful result or a failure.
24+
message ActivityExecutionOutcome {
25+
oneof value {
26+
// The result if the activity completed successfully.
27+
temporal.api.common.v1.Payloads result = 1;
28+
// The failure if the activity completed unsuccessfully.
29+
temporal.api.failure.v1.Failure failure = 2;
30+
}
31+
}
1632

1733
message ActivityOptions {
1834
temporal.api.taskqueue.v1.TaskQueue task_queue = 1;
@@ -40,10 +56,142 @@ message ActivityOptions {
4056
google.protobuf.Duration start_to_close_timeout = 4;
4157
// Maximum permitted time between successful worker heartbeats.
4258
google.protobuf.Duration heartbeat_timeout = 5;
43-
59+
// The retry policy for the activity. Will never exceed `schedule_to_close_timeout`.
4460
temporal.api.common.v1.RetryPolicy retry_policy = 6;
4561

4662
// Priority metadata. If this message is not present, or any fields are not
4763
// present, they inherit the values from the workflow.
4864
temporal.api.common.v1.Priority priority = 7;
49-
}
65+
}
66+
67+
// Information about a standalone activity.
68+
message ActivityExecutionInfo {
69+
// Unique identifier of this activity within its namespace along with run ID (below).
70+
string activity_id = 1;
71+
string run_id = 2;
72+
73+
// The type of the activity, a string that maps to a registered activity on a worker.
74+
temporal.api.common.v1.ActivityType activity_type = 3;
75+
// A general status for this activity, indicates whether it is currently running or in one of the terminal statuses.
76+
temporal.api.enums.v1.ActivityExecutionStatus status = 4;
77+
// More detailed breakdown of ACTIVITY_EXECUTION_STATUS_RUNNING.
78+
temporal.api.enums.v1.PendingActivityState run_state = 5;
79+
80+
string task_queue = 6;
81+
82+
// Indicates how long the caller is willing to wait for an activity completion. Limits how long
83+
// retries will be attempted.
84+
//
85+
// (-- api-linter: core::0140::prepositions=disabled
86+
// aip.dev/not-precedent: "to" is used to indicate interval. --)
87+
google.protobuf.Duration schedule_to_close_timeout = 7;
88+
// Limits time an activity task can stay in a task queue before a worker picks it up. This
89+
// timeout is always non retryable, as all a retry would achieve is to put it back into the same
90+
// queue. Defaults to `schedule_to_close_timeout`.
91+
//
92+
// (-- api-linter: core::0140::prepositions=disabled
93+
// aip.dev/not-precedent: "to" is used to indicate interval. --)
94+
google.protobuf.Duration schedule_to_start_timeout = 8;
95+
// Maximum time a single activity attempt is allowed to execute after being picked up by a worker. This
96+
// timeout is always retryable.
97+
//
98+
// (-- api-linter: core::0140::prepositions=disabled
99+
// aip.dev/not-precedent: "to" is used to indicate interval. --)
100+
google.protobuf.Duration start_to_close_timeout = 9;
101+
102+
// Maximum permitted time between successful worker heartbeats.
103+
google.protobuf.Duration heartbeat_timeout = 10;
104+
105+
// The retry policy for the activity. Will never exceed `schedule_to_close_timeout`.
106+
temporal.api.common.v1.RetryPolicy retry_policy = 11;
107+
108+
// Details provided in the last recorded activity heartbeat.
109+
temporal.api.common.v1.Payloads heartbeat_details = 12;
110+
// Time the last heartbeat was recorded.
111+
google.protobuf.Timestamp last_heartbeat_time = 13;
112+
// Time the last attempt was started.
113+
google.protobuf.Timestamp last_started_time = 14;
114+
// The attempt this activity is currently on. Incremented each time a new attempt is scheduled.
115+
int32 attempt = 15;
116+
// How long this activity has been running for, including all attempts and backoff between attempts.
117+
google.protobuf.Duration execution_duration = 16;
118+
// Time the activity was originally scheduled via a StartActivityExecution request.
119+
google.protobuf.Timestamp schedule_time = 17;
120+
// Scheduled time + schedule to close timeout.
121+
google.protobuf.Timestamp expiration_time = 18;
122+
// Time when the activity transitioned to a closed state.
123+
google.protobuf.Timestamp close_time = 19;
124+
125+
// Failure details from the last failed attempt.
126+
temporal.api.failure.v1.Failure last_failure = 20;
127+
string last_worker_identity = 21;
128+
129+
// Time from the last attempt failure to the next activity retry.
130+
// If the activity is currently running, this represents the next retry interval in case the attempt fails.
131+
// If activity is currently backing off between attempt, this represents the current retry interval.
132+
// If there is no next retry allowed, this field will be null.
133+
// This interval is typically calculated from the specified retry policy, but may be modified if an activity fails
134+
// with a retryable application failure specifying a retry delay.
135+
google.protobuf.Duration current_retry_interval = 22;
136+
137+
// The time when the last activity attempt completed. If activity has not been completed yet, it will be null.
138+
google.protobuf.Timestamp last_attempt_complete_time = 23;
139+
140+
// The time when the next activity attempt will be scheduled.
141+
// If activity is currently scheduled or started, this field will be null.
142+
google.protobuf.Timestamp next_attempt_schedule_time = 24;
143+
144+
// The Worker Deployment Version this activity was dispatched to most recently.
145+
// If nil, the activity has not yet been dispatched or was last dispatched to an unversioned worker.
146+
temporal.api.deployment.v1.WorkerDeploymentVersion last_deployment_version = 25;
147+
148+
// Priority metadata.
149+
temporal.api.common.v1.Priority priority = 26;
150+
151+
// Incremented each time the activity's state is mutated in persistence.
152+
int64 state_transition_count = 27;
153+
154+
// Updated once on scheduled and once on terminal status.
155+
int64 state_size_bytes = 28;
156+
157+
temporal.api.common.v1.SearchAttributes search_attributes = 29;
158+
temporal.api.common.v1.Header header = 30;
159+
// Metadata for use by user interfaces to display the fixed as-of-start summary and details of the activity.
160+
temporal.api.sdk.v1.UserMetadata user_metadata = 31;
161+
162+
// Set if activity cancelation was requested.
163+
string canceled_reason = 32;
164+
}
165+
166+
// Limited activity information returned in the list response.
167+
// When adding fields here, ensure that it is also present in ActivityExecutionInfo (note that it
168+
// may already be present in ActivityExecutionInfo but not at the top-level).
169+
message ActivityExecutionListInfo {
170+
// A unique identifier of this activity within its namespace along with run ID (below).
171+
string activity_id = 1;
172+
// The run ID of the standalone activity.
173+
string run_id = 2;
174+
175+
// The type of the activity, a string that maps to a registered activity on a worker.
176+
temporal.api.common.v1.ActivityType activity_type = 3;
177+
// Time the activity was originally scheduled via a StartActivityExecution request.
178+
google.protobuf.Timestamp schedule_time = 4;
179+
// If the activity is in a terminal status, this field represents the time the activity transitioned to that status.
180+
google.protobuf.Timestamp close_time = 5;
181+
// Only scheduled and terminal statuses appear here. More detailed information in PendingActivityInfo but not
182+
// available in the list response.
183+
temporal.api.enums.v1.ActivityExecutionStatus status = 6;
184+
185+
// Search attributes from the start request.
186+
temporal.api.common.v1.SearchAttributes search_attributes = 7;
187+
188+
// The task queue this activity was scheduled on when it was originally started, updated on activity options update.
189+
string task_queue = 8;
190+
// Updated on terminal status.
191+
int64 state_transition_count = 9;
192+
// Updated once on scheduled and once on terminal status.
193+
int64 state_size_bytes = 10;
194+
// The difference between close time and scheduled time.
195+
// This field is only populated if the activity is closed.
196+
google.protobuf.Duration execution_duration = 11;
197+
}

temporal/api/common/v1/message.proto

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,4 +346,3 @@ message WorkerSelector {
346346
string worker_instance_key = 1;
347347
}
348348
}
349-
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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+
// (-- api-linter: core::0216::synonyms=disabled
16+
// aip.dev/not-precedent: Named consistently with WorkflowExecutionStatus. --)
17+
enum ActivityExecutionStatus {
18+
ACTIVITY_EXECUTION_STATUS_UNSPECIFIED = 0;
19+
20+
// The activity has not reached a terminal status. See PendingActivityState for the run state
21+
// (SCHEDULED, STARTED, or CANCEL_REQUESTED).
22+
ACTIVITY_EXECUTION_STATUS_RUNNING = 1;
23+
24+
// The activity completed successfully. An activity can complete even after cancellation is
25+
// requested if the worker calls RespondActivityTaskCompleted before acknowledging cancellation.
26+
ACTIVITY_EXECUTION_STATUS_COMPLETED = 2;
27+
28+
// The activity failed. Causes:
29+
// - Worker returned a non-retryable failure
30+
// - RetryPolicy.maximum_attempts exhausted
31+
// - Attempt failed after cancellation was requested (retries blocked)
32+
ACTIVITY_EXECUTION_STATUS_FAILED = 3;
33+
34+
// The activity was canceled. Reached when:
35+
// - Cancellation requested while SCHEDULED (immediate), or
36+
// - Cancellation requested while STARTED and worker called RespondActivityTaskCanceled.
37+
//
38+
// Workers discover cancellation requests via heartbeat responses (cancel_requested=true).
39+
// Activities that do not heartbeat will not learn of cancellation and may complete, fail, or
40+
// time out normally. CANCELED requires explicit worker acknowledgment or immediate cancellation
41+
// of a SCHEDULED activity.
42+
ACTIVITY_EXECUTION_STATUS_CANCELED = 4;
43+
44+
// The activity was terminated. Immediate; does not wait for worker acknowledgment.
45+
ACTIVITY_EXECUTION_STATUS_TERMINATED = 5;
46+
47+
// The activity timed out. See TimeoutType for the specific timeout.
48+
// - SCHEDULE_TO_START and SCHEDULE_TO_CLOSE timeouts always result in TIMED_OUT.
49+
// - START_TO_CLOSE and HEARTBEAT may retry if RetryPolicy permits; TIMED_OUT is
50+
// reached when retry is blocked (RetryPolicy.maximum_attempts exhausted,
51+
// SCHEDULE_TO_CLOSE would be exceeded, or cancellation has been requested).
52+
ACTIVITY_EXECUTION_STATUS_TIMED_OUT = 6;
53+
}
54+
55+
// Defines whether to allow re-using an activity ID from a previously *closed* activity.
56+
// If the request is denied, the server returns an `ActivityExecutionAlreadyStarted` error.
57+
//
58+
// See `ActivityIdConflictPolicy` for handling ID duplication with a *running* activity.
59+
enum ActivityIdReusePolicy {
60+
ACTIVITY_ID_REUSE_POLICY_UNSPECIFIED = 0;
61+
// Always allow starting an activity using the same activity ID.
62+
ACTIVITY_ID_REUSE_POLICY_ALLOW_DUPLICATE = 1;
63+
// Allow starting an activity using the same ID only when the last activity's final state is one
64+
// of {failed, canceled, terminated, timed out}.
65+
ACTIVITY_ID_REUSE_POLICY_ALLOW_DUPLICATE_FAILED_ONLY = 2;
66+
// Do not permit re-use of the ID for this activity. Future start requests could potentially change the policy,
67+
// allowing re-use of the ID.
68+
ACTIVITY_ID_REUSE_POLICY_REJECT_DUPLICATE = 3;
69+
}
70+
71+
// Defines what to do when trying to start an activity with the same ID as a *running* activity.
72+
// Note that it is *never* valid to have two running instances of the same activity ID.
73+
//
74+
// See `ActivityIdReusePolicy` for handling activity ID duplication with a *closed* activity.
75+
enum ActivityIdConflictPolicy {
76+
ACTIVITY_ID_CONFLICT_POLICY_UNSPECIFIED = 0;
77+
// Don't start a new activity; instead return `ActivityExecutionAlreadyStarted` error.
78+
ACTIVITY_ID_CONFLICT_POLICY_FAIL = 1;
79+
// Don't start a new activity; instead return a handle for the running activity.
80+
ACTIVITY_ID_CONFLICT_POLICY_USE_EXISTING = 2;
81+
}

temporal/api/errordetails/v1/message.proto

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,11 @@ message MultiOperationExecutionFailure {
121121
repeated google.protobuf.Any details = 3;
122122
}
123123
}
124+
125+
// An error indicating that an activity execution failed to start. Returned when there is an existing activity with the
126+
// given activity ID, and the given ID reuse and conflict policies do not permit starting a new one or attaching to an
127+
// existing one.
128+
message ActivityExecutionAlreadyStartedFailure {
129+
string start_request_id = 1;
130+
string run_id = 2;
131+
}

0 commit comments

Comments
 (0)