Add orchestration send_event support - #225
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 42bcd2ff-9f6f-4235-81b5-629d07ecaa30
There was a problem hiding this comment.
Pull request overview
Adds orchestration-to-orchestration one-way event sending to the core Durable Task Python SDK, including deterministic action emission and replay reconciliation, plus in-memory backend delivery behavior and coverage.
Changes:
- Introduces
OrchestrationContext.send_event(instance_id, event_name, *, data=None)and emitsSendEventActionrecords using the configuredDataConverter. - Reconciles
EventSenthistory during replay (including case-insensitive event-name matching) and wires action-type name resolution forsendEvent. - Extends the in-memory backend to persist
EventSenthistory and deliver/drop sent events safely without duplicate replay delivery; adds unit/E2E/large-payload tests and a changelog entry.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/durabletask/test_orchestration_executor.py | Adds unit tests covering send-event action creation, converter usage, validation, and replay nondeterminism behavior. |
| tests/durabletask/test_orchestration_e2e.py | Adds E2E coverage for orchestration-to-orchestration event delivery and replay-safe non-duplication behavior. |
| tests/durabletask/test_large_payload.py | Verifies large send-event payloads are externalized. |
| durabletask/worker.py | Implements send_event, reconciles EventSent during replay, and maps sendEvent actions to the correct method name. |
| durabletask/testing/in_memory_backend.py | Records EventSent history and delivers/drops send-event actions in the in-memory backend. |
| durabletask/task.py | Declares the public send_event API on OrchestrationContext. |
| durabletask/internal/helpers.py | Adds helpers to build SendEventAction and enrich EventSent history with an event name. |
| CHANGELOG.md | Documents the new OrchestrationContext.send_event() API under Unreleased/ADDED. |
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 42bcd2ff-9f6f-4235-81b5-629d07ecaa30
| """ | ||
| pass | ||
|
|
||
| @abstractmethod |
There was a problem hiding this comment.
Making this new method abstract breaks every existing third-party or test OrchestrationContext subclass that implements the previous public contract: after upgrading, instantiation raises TypeError even when send_event() is never used. Keep a concrete default that raises NotImplementedError, or defer the abstract requirement to a major version, so this additive API remains backward compatible.
There was a problem hiding this comment.
I agree this can affect custom subclasses, but keeping the method abstract is consistent with this interface's contract and the project's release precedent. parent_instance_id was added as an abstract property in #168 and shipped between v1.7.0 and the v1.7.1 patch release; new_uuid was also added abstract in #83 before v1.2.0. I therefore prefer the consistent fail-fast requirement here over deferring an omitted implementation to runtime.
There was a problem hiding this comment.
Those precedents do not make this additive API backward compatible: a subclass built against the current public contract now fails at instantiation even when it never calls send_event(). The break is avoidable—keep a concrete default that raises NotImplementedError when invoked, and reserve adding an abstract requirement for a major release.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 42bcd2ff-9f6f-4235-81b5-629d07ecaa30
Summary
OrchestrationContext.send_event(instance_id, event_name, *, data=None)for one-way orchestration-to-orchestration eventsSendEventActionrecords using the configured data converter and reconcileEventSenthistory during replay using .NET-compatible event-name matchingValidation
python -m nox -s ci -- 3.14python -m nox -R -s core_tests-3.14 -- tests\durabletask\test_orchestration_executor.py tests\durabletask\test_orchestration_e2e.py tests\durabletask\test_large_payload.py -qpython -m nox -R -s lintpython -m nox -R -s typecheck_core-3.10Closes #32