|
7 | 7 | import math |
8 | 8 | from abc import ABC, abstractmethod |
9 | 9 | from datetime import datetime, timedelta |
10 | | -from typing import Any, Callable, Generator, Generic, Optional, TypeVar, Union |
| 10 | +from typing import Any, Callable, Generator, Generic, Optional, Type, TypeVar, Union |
11 | 11 |
|
| 12 | +from durabletask.entities.entity_instance_id import EntityInstanceId |
| 13 | +from durabletask.internal.entity_lock_releaser import EntityLockReleaser |
| 14 | +from durabletask.internal.entity_state_shim import StateShim |
12 | 15 | import durabletask.internal.helpers as pbh |
13 | 16 | import durabletask.internal.orchestrator_service_pb2 as pb |
14 | 17 |
|
@@ -137,6 +140,55 @@ def call_activity(self, activity: Union[Activity[TInput, TOutput], str], *, |
137 | 140 | """ |
138 | 141 | pass |
139 | 142 |
|
| 143 | + @abstractmethod |
| 144 | + def call_entity(self, entity: EntityInstanceId, *, |
| 145 | + input: Optional[TInput] = None): |
| 146 | + """Schedule entity function for execution. |
| 147 | +
|
| 148 | + Parameters |
| 149 | + ---------- |
| 150 | + entity: EntityInstanceId |
| 151 | + The ID of the entity instance to call. |
| 152 | + input: Optional[TInput] |
| 153 | + The optional JSON-serializable input to pass to the entity function. |
| 154 | +
|
| 155 | + Returns |
| 156 | + ------- |
| 157 | + Task |
| 158 | + A Durable Task that completes when the called entity function completes or fails. |
| 159 | + """ |
| 160 | + pass |
| 161 | + |
| 162 | + @abstractmethod |
| 163 | + def signal_entity( |
| 164 | + self, |
| 165 | + entity_id: EntityInstanceId |
| 166 | + ) -> None: |
| 167 | + """Signal an entity function for execution. |
| 168 | +
|
| 169 | + Parameters |
| 170 | + ---------- |
| 171 | + entity_id: EntityInstanceId |
| 172 | + The ID of the entity instance to signal. |
| 173 | + """ |
| 174 | + pass |
| 175 | + |
| 176 | + @abstractmethod |
| 177 | + def lock_entities(self, entities: list[EntityInstanceId]) -> EntityLockReleaser: |
| 178 | + """Lock the specified entity instances for the duration of the orchestration. |
| 179 | +
|
| 180 | + Parameters |
| 181 | + ---------- |
| 182 | + entities: list[EntityInstanceId] |
| 183 | + The list of entity instance IDs to lock. |
| 184 | +
|
| 185 | + Returns |
| 186 | + ------- |
| 187 | + EntityLockReleaser |
| 188 | + A context manager that releases the locks when disposed. |
| 189 | + """ |
| 190 | + pass |
| 191 | + |
140 | 192 | @abstractmethod |
141 | 193 | def call_sub_orchestrator(self, orchestrator: Orchestrator[TInput, TOutput], *, |
142 | 194 | input: Optional[TInput] = None, |
@@ -452,12 +504,65 @@ def task_id(self) -> int: |
452 | 504 | return self._task_id |
453 | 505 |
|
454 | 506 |
|
| 507 | +class EntityContext: |
| 508 | + def __init__(self, orchestration_id: str, operation: str, state: StateShim, entity_id: EntityInstanceId): |
| 509 | + self._orchestration_id = orchestration_id |
| 510 | + self._operation = operation |
| 511 | + self._state = state |
| 512 | + self._entity_id = entity_id |
| 513 | + |
| 514 | + @property |
| 515 | + def orchestration_id(self) -> str: |
| 516 | + """Get the ID of the orchestration instance that scheduled this entity. |
| 517 | +
|
| 518 | + Returns |
| 519 | + ------- |
| 520 | + str |
| 521 | + The ID of the current orchestration instance. |
| 522 | + """ |
| 523 | + return self._orchestration_id |
| 524 | + |
| 525 | + @property |
| 526 | + def operation(self) -> str: |
| 527 | + """Get the operation associated with this entity invocation. |
| 528 | +
|
| 529 | + The operation is a string that identifies the specific action being |
| 530 | + performed on the entity. It can be used to distinguish between |
| 531 | + multiple operations that are part of the same entity invocation. |
| 532 | +
|
| 533 | + Returns |
| 534 | + ------- |
| 535 | + str |
| 536 | + The operation associated with this entity invocation. |
| 537 | + """ |
| 538 | + return self._operation |
| 539 | + |
| 540 | + def get_state(self, intended_type: Optional[Type] = None): |
| 541 | + return self._state.get_state(intended_type) |
| 542 | + |
| 543 | + def set_state(self, new_state): |
| 544 | + self._state.set_state(new_state) |
| 545 | + |
| 546 | + @property |
| 547 | + def entity_id(self) -> EntityInstanceId: |
| 548 | + """Get the ID of the entity instance. |
| 549 | +
|
| 550 | + Returns |
| 551 | + ------- |
| 552 | + str |
| 553 | + The ID of the current entity instance. |
| 554 | + """ |
| 555 | + return self._entity_id |
| 556 | + |
| 557 | + |
455 | 558 | # Orchestrators are generators that yield tasks and receive/return any type |
456 | 559 | Orchestrator = Callable[[OrchestrationContext, TInput], Union[Generator[Task, Any, Any], TOutput]] |
457 | 560 |
|
458 | 561 | # Activities are simple functions that can be scheduled by orchestrators |
459 | 562 | Activity = Callable[[ActivityContext, TInput], TOutput] |
460 | 563 |
|
| 564 | +Entity = Callable[[EntityContext, TInput], TOutput] |
| 565 | + |
461 | 566 |
|
462 | 567 | class RetryPolicy: |
463 | 568 | """Represents the retry policy for an orchestration or activity function.""" |
|
0 commit comments