Skip to content

Commit 904c04f

Browse files
committed
Implement the rest of the spec
1 parent ad5d081 commit 904c04f

9 files changed

Lines changed: 2732 additions & 2684 deletions

File tree

cross-sdk-design.md

Lines changed: 0 additions & 2334 deletions
This file was deleted.

temporalio/activity.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
TYPE_CHECKING,
2424
Any,
2525
NoReturn,
26-
Type,
2726
overload,
2827
)
2928

@@ -106,25 +105,24 @@ class Info:
106105
heartbeat_timeout: timedelta | None
107106
is_local: bool
108107
namespace: str
109-
"""Namespace the activity is running in."""
110108
schedule_to_close_timeout: timedelta | None
111109
scheduled_time: datetime
112110
start_to_close_timeout: timedelta | None
113111
started_time: datetime
114112
task_queue: str
115113
task_token: bytes
116114
workflow_id: str | None
117-
"""ID of the workflow that started this activity. None for standalone activities."""
115+
"""ID of the workflow. None if the activity was not started by a workflow."""
118116
workflow_namespace: str | None
119-
"""Namespace of the workflow that started this activity. None for standalone activities.
117+
"""Namespace of the workflow. None if the activity was not started by a workflow.
120118
121119
.. deprecated::
122120
Use :py:attr:`namespace` instead.
123121
"""
124122
workflow_run_id: str | None
125-
"""Run ID of the workflow that started this activity. None for standalone activities."""
123+
"""Run ID of the workflow. None if the activity was not started by a workflow."""
126124
workflow_type: str | None
127-
"""Type of the workflow that started this activity. None for standalone activities."""
125+
"""Type of the workflow. None if the activity was not started by a workflow."""
128126
priority: temporalio.common.Priority
129127
retry_policy: temporalio.common.RetryPolicy | None
130128
"""The retry policy of this activity.
@@ -134,11 +132,11 @@ class Info:
134132
version), but it may still be defined server-side."""
135133

136134
activity_run_id: str | None = None
137-
"""Run ID of this standalone activity. None for workflow activities."""
135+
"""Run ID of this activity. None for workflow activities."""
138136

139137
@property
140138
def in_workflow(self) -> bool:
141-
"""Whether this activity was started by a workflow (vs. standalone)."""
139+
"""Was this activity started by a workflow?"""
142140
return self.workflow_id is not None
143141

144142
# TODO(cretz): Consider putting identity on here for "worker_id" for logger?
@@ -599,7 +597,7 @@ def must_from_callable(fn: Callable) -> _Definition:
599597
@classmethod
600598
def get_name_and_result_type(
601599
cls, name_or_run_fn: str | Callable[..., Any]
602-
) -> tuple[str, Type | None]:
600+
) -> tuple[str, type | None]:
603601
if isinstance(name_or_run_fn, str):
604602
return name_or_run_fn, None
605603
elif callable(name_or_run_fn):
@@ -608,7 +606,7 @@ def get_name_and_result_type(
608606
raise ValueError(f"Activity {name_or_run_fn} definition has no name")
609607
return defn.name, defn.ret_type
610608
else:
611-
raise TypeError("Activity must be a string or callable")
609+
raise TypeError("Activity must be a string or callable") # type:ignore[reportUnreachable]
612610

613611
@staticmethod
614612
def _apply_to_callable(

temporalio/client.py

Lines changed: 1260 additions & 269 deletions
Large diffs are not rendered by default.

temporalio/common.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -190,25 +190,39 @@ class ActivityIDConflictPolicy(IntEnum):
190190

191191

192192
class ActivityExecutionStatus(IntEnum):
193-
"""Status of a standalone activity execution.
193+
"""Status of an activity execution.
194194
195195
.. warning::
196196
This API is experimental.
197197
198198
See :py:class:`temporalio.api.enums.v1.ActivityExecutionStatus`.
199199
"""
200200

201-
UNSPECIFIED = 0 # ACTIVITY_EXECUTION_STATUS_UNSPECIFIED
202-
RUNNING = 1 # ACTIVITY_EXECUTION_STATUS_RUNNING
203-
COMPLETED = 2 # ACTIVITY_EXECUTION_STATUS_COMPLETED
204-
FAILED = 3 # ACTIVITY_EXECUTION_STATUS_FAILED
205-
CANCELED = 4 # ACTIVITY_EXECUTION_STATUS_CANCELED
206-
TERMINATED = 5 # ACTIVITY_EXECUTION_STATUS_TERMINATED
207-
TIMED_OUT = 6 # ACTIVITY_EXECUTION_STATUS_TIMED_OUT
201+
UNSPECIFIED = int(
202+
temporalio.api.enums.v1.ActivityExecutionStatus.ACTIVITY_EXECUTION_STATUS_UNSPECIFIED
203+
)
204+
RUNNING = int(
205+
temporalio.api.enums.v1.ActivityExecutionStatus.ACTIVITY_EXECUTION_STATUS_RUNNING
206+
)
207+
COMPLETED = int(
208+
temporalio.api.enums.v1.ActivityExecutionStatus.ACTIVITY_EXECUTION_STATUS_COMPLETED
209+
)
210+
FAILED = int(
211+
temporalio.api.enums.v1.ActivityExecutionStatus.ACTIVITY_EXECUTION_STATUS_FAILED
212+
)
213+
CANCELED = int(
214+
temporalio.api.enums.v1.ActivityExecutionStatus.ACTIVITY_EXECUTION_STATUS_CANCELED
215+
)
216+
TERMINATED = int(
217+
temporalio.api.enums.v1.ActivityExecutionStatus.ACTIVITY_EXECUTION_STATUS_TERMINATED
218+
)
219+
TIMED_OUT = int(
220+
temporalio.api.enums.v1.ActivityExecutionStatus.ACTIVITY_EXECUTION_STATUS_TIMED_OUT
221+
)
208222

209223

210224
class PendingActivityState(IntEnum):
211-
"""State of a pending activity.
225+
"""Detailed state of an activity execution that is in ACTIVITY_EXECUTION_STATUS_RUNNING.
212226
213227
.. warning::
214228
This API is experimental.

temporalio/converter.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class WorkflowSerializationContext(SerializationContext):
9898
namespace: str
9999
"""Namespace."""
100100

101-
workflow_id: Optional[str]
101+
workflow_id: str | None
102102
"""Workflow ID."""
103103

104104

@@ -117,13 +117,13 @@ class ActivitySerializationContext(SerializationContext):
117117
this may be the workflow ID prefix as configured, not the final workflow ID when the
118118
workflow is created by the schedule.
119119
workflow_type: Workflow Type. Only set if this is an activity started from a workflow.
120-
is_local: Whether the activity is a local activity. False if this is a standalone activity started directly by a client.
120+
is_local: Whether the activity is a local activity. False if the activity was not started by a workflow.
121121
"""
122122

123123
namespace: str
124124
"""Namespace."""
125125

126-
activity_id: Optional[str]
126+
activity_id: str | None
127127
"""Activity ID. Optional if this is an activity started from a workflow."""
128128

129129
activity_type: str
@@ -132,10 +132,10 @@ class ActivitySerializationContext(SerializationContext):
132132
activity_task_queue: str
133133
"""Activity task queue."""
134134

135-
workflow_id: Optional[str]
135+
workflow_id: str | None
136136
"""Workflow ID if this is an activity started from a workflow."""
137137

138-
workflow_type: Optional[str]
138+
workflow_type: str | None
139139
"""Workflow type if this is an activity started from a workflow."""
140140

141141
is_local: bool

temporalio/exceptions.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,9 @@ class RetryState(IntEnum):
248248

249249

250250
# TODO: This error class has required history event fields. I propose we retain it as
251-
# workflow-specific and introduce client.ActivityFailureError for an error in a standalone activity.
252-
# We could deprecate this name and introduce WorkflowActivityError as a preferred-going-forwards
253-
# alias.
251+
# workflow-specific and introduce client.ActivityFailedError for an error in an activity not
252+
# started by a workflow. We could deprecate this name and introduce WorkflowActivityError as a
253+
# preferred-going-forwards alias.
254254
class ActivityError(FailureError):
255255
"""Error raised on activity failure."""
256256

temporalio/worker/_activity.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ async def _handle_start_activity_task(
303303
)
304304
# Create serialization context for the activity
305305
context = temporalio.converter.ActivitySerializationContext(
306-
namespace=start.workflow_namespace,
306+
namespace=start.workflow_namespace or self._client.namespace,
307307
workflow_id=start.workflow_execution.workflow_id,
308308
workflow_type=start.workflow_type,
309309
activity_type=start.activity_type,
@@ -547,8 +547,7 @@ async def _execute_activity(
547547
) from err
548548

549549
# Build info
550-
# Determine if this is a standalone activity
551-
is_standalone = not start.workflow_execution.workflow_id
550+
started_by_workflow = bool(start.workflow_execution.workflow_id)
552551
info = temporalio.activity.Info(
553552
activity_id=start.activity_id,
554553
activity_type=start.activity_type,
@@ -584,7 +583,9 @@ async def _execute_activity(
584583
retry_policy=temporalio.common.RetryPolicy.from_proto(start.retry_policy)
585584
if start.HasField("retry_policy")
586585
else None,
587-
activity_run_id=getattr(start, "run_id", None) if is_standalone else None,
586+
activity_run_id=getattr(start, "run_id", None)
587+
if not started_by_workflow
588+
else None,
588589
)
589590

590591
if self._encode_headers and data_converter.payload_codec is not None:

0 commit comments

Comments
 (0)