-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathparallel_saga.py
More file actions
40 lines (32 loc) · 1.57 KB
/
Copy pathparallel_saga.py
File metadata and controls
40 lines (32 loc) · 1.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
"""Workflow-only examples for deterministic parallel groups and sagas."""
from durable_workflow import ChildWorkflowFailed, workflow
@workflow.defn(name="parallel-trip-quote")
class ParallelTripQuote:
def run(self, ctx): # type: ignore[no-untyped-def]
try:
return (
yield [
ctx.schedule_activity("trip.quote-flight", []),
[
ctx.start_child_workflow("trip.quote-hotel", []),
ctx.start_timer(1),
],
]
)
except ChildWorkflowFailed as failure:
return {"failed_child": failure.child_workflow_type, "message": str(failure)}
@workflow.defn(name="trip-booking-saga")
class TripBookingSaga:
def run(self, ctx): # type: ignore[no-untyped-def]
def forward(saga): # type: ignore[no-untyped-def]
flight = yield ctx.schedule_activity("trip.reserve-flight", [])
saga.add_compensation("trip.cancel-flight", [flight])
hotel = yield ctx.schedule_activity("trip.reserve-hotel", [])
saga.add_compensation("trip.cancel-hotel", [hotel])
ctx.throw_if_cancellation_requested()
yield ctx.schedule_activity("trip.charge", [])
return {"flight": flight, "hotel": hotel}
# A worker restart or completed-history replay reconstructs every
# registration. Compensation failure is surfaced as the exported
# SagaCompensationFailed type with both failures retained.
return (yield from ctx.saga().run(forward))