Skip to content

Commit 3c05264

Browse files
committed
Add remaining orchestration surface
1 parent a1b54bd commit 3c05264

3 files changed

Lines changed: 88 additions & 0 deletions

File tree

azure-functions-durable/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3131
Two-argument (durabletask-native) orchestrators continue to work unchanged.
3232
`DurableOrchestrationContext.call_http` raises `NotImplementedError` pending a
3333
durabletask durable-HTTP implementation.
34+
- `DurableOrchestrationContext` also exposes `custom_status` (reflecting the
35+
value set via `set_custom_status`) and `will_continue_as_new` (True once
36+
`continue_as_new` has been called). `parent_instance_id`, `function_context`,
37+
and `histories` raise `NotImplementedError` because durabletask does not
38+
surface that information on the orchestration context.
3439

3540
- Backwards-compatible, deprecated aliases on `DurableFunctionsClient` for the
3641
v1 `DurableOrchestrationClient` method names: `start_new`, `get_status`,

azure-functions-durable/azure/durable_functions/internal/compat/orchestration_context.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ class DurableOrchestrationContext:
2727
def __init__(self, ctx: OrchestrationContext, orchestration_input: Any = None):
2828
self._ctx = ctx
2929
self._input = orchestration_input
30+
self._custom_status: Any = None
31+
self._will_continue_as_new = False
3032

3133
# -- input ---------------------------------------------------------------
3234
def get_input(self) -> Any:
@@ -49,6 +51,47 @@ def current_utc_datetime(self) -> datetime:
4951
"""Get the replay-safe current UTC date/time."""
5052
return self._ctx.current_utc_datetime
5153

54+
@property
55+
def custom_status(self) -> Any:
56+
"""Get the custom status set during this execution (or ``None``)."""
57+
return self._custom_status
58+
59+
@property
60+
def will_continue_as_new(self) -> bool:
61+
"""Whether :meth:`continue_as_new` has been called in this execution."""
62+
return self._will_continue_as_new
63+
64+
@property
65+
def parent_instance_id(self) -> str:
66+
"""Get the ID of the parent orchestration.
67+
68+
Not available: durabletask does not currently surface the parent
69+
instance ID on the orchestration context.
70+
"""
71+
raise NotImplementedError(
72+
"parent_instance_id is not currently exposed by durabletask.")
73+
74+
@property
75+
def function_context(self) -> Any:
76+
"""Get the Azure Functions-level context.
77+
78+
Not available: durabletask does not provide the v1 ``FunctionContext``
79+
binding metadata.
80+
"""
81+
raise NotImplementedError(
82+
"function_context is not available in this SDK.")
83+
84+
@property
85+
def histories(self) -> Any:
86+
"""Get the running history of scheduled tasks.
87+
88+
Not available: durabletask manages orchestration history internally and
89+
does not expose it on the context.
90+
"""
91+
raise NotImplementedError(
92+
"histories is not exposed by durabletask; use the client's "
93+
"get_orchestration_history instead.")
94+
5295
# -- activities ----------------------------------------------------------
5396
def call_activity(self, name: Callable[..., Any] | str, input_: Any = None) -> Task[Any]:
5497
"""Schedule an activity function for execution."""
@@ -92,10 +135,12 @@ def wait_for_external_event(self,
92135
# -- control -------------------------------------------------------------
93136
def continue_as_new(self, input_: Any) -> None:
94137
"""Restart the orchestration with a new input."""
138+
self._will_continue_as_new = True
95139
self._ctx.continue_as_new(input_)
96140

97141
def set_custom_status(self, status: Any) -> None:
98142
"""Set the orchestration's custom status payload."""
143+
self._custom_status = status
99144
self._ctx.set_custom_status(status)
100145

101146
# -- deterministic IDs ---------------------------------------------------

tests/azure-functions-durable/test_orchestration_context_compat.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,44 @@ def test_call_http_raises_not_implemented():
116116
adapter.call_http("GET", "http://example.com")
117117

118118

119+
# ---------------------------------------------------------------------------
120+
# Additional context members
121+
# ---------------------------------------------------------------------------
122+
123+
def test_custom_status_tracks_set_custom_status():
124+
adapter, fake = _adapter()
125+
assert adapter.custom_status is None
126+
adapter.set_custom_status({"progress": 50})
127+
assert adapter.custom_status == {"progress": 50}
128+
fake.set_custom_status.assert_called_once_with({"progress": 50})
129+
130+
131+
def test_will_continue_as_new_tracks_continue_as_new():
132+
adapter, fake = _adapter()
133+
assert adapter.will_continue_as_new is False
134+
adapter.continue_as_new({"next": 1})
135+
assert adapter.will_continue_as_new is True
136+
fake.continue_as_new.assert_called_once_with({"next": 1})
137+
138+
139+
def test_parent_instance_id_raises_not_implemented():
140+
adapter, _ = _adapter()
141+
with pytest.raises(NotImplementedError):
142+
_ = adapter.parent_instance_id
143+
144+
145+
def test_function_context_raises_not_implemented():
146+
adapter, _ = _adapter()
147+
with pytest.raises(NotImplementedError):
148+
_ = adapter.function_context
149+
150+
151+
def test_histories_raises_not_implemented():
152+
adapter, _ = _adapter()
153+
with pytest.raises(NotImplementedError):
154+
_ = adapter.histories
155+
156+
119157
# ---------------------------------------------------------------------------
120158
# Arity detection and wrapping
121159
# ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)