|
2 | 2 | # Licensed under the MIT License. |
3 | 3 |
|
4 | 4 | import logging |
| 5 | +import uuid |
5 | 6 | from dataclasses import dataclass |
6 | 7 | from datetime import datetime |
7 | 8 | from enum import Enum |
|
16 | 17 | import durabletask.internal.orchestrator_service_pb2 as pb |
17 | 18 | import durabletask.internal.orchestrator_service_pb2_grpc as stubs |
18 | 19 | import durabletask.internal.shared as shared |
| 20 | +import durabletask.internal.tracing as tracing |
19 | 21 | from durabletask import task |
20 | 22 | from durabletask.internal.client_helpers import ( |
21 | 23 | build_query_entities_req, |
@@ -176,14 +178,28 @@ def schedule_new_orchestration(self, orchestrator: Union[task.Orchestrator[TInpu |
176 | 178 | tags: Optional[dict[str, str]] = None, |
177 | 179 | version: Optional[str] = None) -> str: |
178 | 180 |
|
179 | | - req = build_schedule_new_orchestration_req( |
180 | | - orchestrator, input=input, instance_id=instance_id, start_at=start_at, |
181 | | - reuse_id_policy=reuse_id_policy, tags=tags, |
182 | | - version=version if version else self.default_version) |
183 | | - |
184 | | - self._logger.info(f"Starting new '{req.name}' instance with ID = '{req.instanceId}'.") |
185 | | - res: pb.CreateInstanceResponse = self._stub.StartInstance(req) |
186 | | - return res.instanceId |
| 181 | + name = orchestrator if isinstance(orchestrator, str) else task.get_name(orchestrator) |
| 182 | + resolved_instance_id = instance_id if instance_id else uuid.uuid4().hex |
| 183 | + resolved_version = version if version else self.default_version |
| 184 | + |
| 185 | + with tracing.start_create_orchestration_span( |
| 186 | + name, resolved_instance_id, version=resolved_version, |
| 187 | + ): |
| 188 | + req = build_schedule_new_orchestration_req( |
| 189 | + orchestrator, input=input, instance_id=instance_id, start_at=start_at, |
| 190 | + reuse_id_policy=reuse_id_policy, tags=tags, |
| 191 | + version=version if version else self.default_version) |
| 192 | + |
| 193 | + # Inject the active PRODUCER span context into the request so the sidecar |
| 194 | + # stores it in the executionStarted event and the worker can parent all |
| 195 | + # orchestration/activity/timer spans under this trace. |
| 196 | + parent_trace_ctx = tracing.get_current_trace_context() |
| 197 | + if parent_trace_ctx is not None: |
| 198 | + req.parentTraceContext.CopyFrom(parent_trace_ctx) |
| 199 | + |
| 200 | + self._logger.info(f"Starting new '{req.name}' instance with ID = '{req.instanceId}'.") |
| 201 | + res: pb.CreateInstanceResponse = self._stub.StartInstance(req) |
| 202 | + return res.instanceId |
187 | 203 |
|
188 | 204 | def get_orchestration_state(self, instance_id: str, *, fetch_payloads: bool = True) -> Optional[OrchestrationState]: |
189 | 205 | req = pb.GetInstanceRequest(instanceId=instance_id, getInputsAndOutputs=fetch_payloads) |
@@ -245,10 +261,10 @@ def wait_for_orchestration_completion(self, instance_id: str, *, |
245 | 261 |
|
246 | 262 | def raise_orchestration_event(self, instance_id: str, event_name: str, *, |
247 | 263 | data: Optional[Any] = None) -> None: |
248 | | - req = build_raise_event_req(instance_id, event_name, data) |
249 | | - |
250 | | - self._logger.info(f"Raising event '{event_name}' for instance '{instance_id}'.") |
251 | | - self._stub.RaiseEvent(req) |
| 264 | + with tracing.start_raise_event_span(event_name, instance_id): |
| 265 | + req = build_raise_event_req(instance_id, event_name, data) |
| 266 | + self._logger.info(f"Raising event '{event_name}' for instance '{instance_id}'.") |
| 267 | + self._stub.RaiseEvent(req) |
252 | 268 |
|
253 | 269 | def terminate_orchestration(self, instance_id: str, *, |
254 | 270 | output: Optional[Any] = None, |
@@ -418,14 +434,25 @@ async def schedule_new_orchestration(self, orchestrator: Union[task.Orchestrator |
418 | 434 | tags: Optional[dict[str, str]] = None, |
419 | 435 | version: Optional[str] = None) -> str: |
420 | 436 |
|
421 | | - req = build_schedule_new_orchestration_req( |
422 | | - orchestrator, input=input, instance_id=instance_id, start_at=start_at, |
423 | | - reuse_id_policy=reuse_id_policy, tags=tags, |
424 | | - version=version if version else self.default_version) |
| 437 | + name = orchestrator if isinstance(orchestrator, str) else task.get_name(orchestrator) |
| 438 | + resolved_instance_id = instance_id if instance_id else uuid.uuid4().hex |
| 439 | + resolved_version = version if version else self.default_version |
425 | 440 |
|
426 | | - self._logger.info(f"Starting new '{req.name}' instance with ID = '{req.instanceId}'.") |
427 | | - res: pb.CreateInstanceResponse = await self._stub.StartInstance(req) |
428 | | - return res.instanceId |
| 441 | + with tracing.start_create_orchestration_span( |
| 442 | + name, resolved_instance_id, version=resolved_version, |
| 443 | + ): |
| 444 | + req = build_schedule_new_orchestration_req( |
| 445 | + orchestrator, input=input, instance_id=instance_id, start_at=start_at, |
| 446 | + reuse_id_policy=reuse_id_policy, tags=tags, |
| 447 | + version=version if version else self.default_version) |
| 448 | + |
| 449 | + parent_trace_ctx = tracing.get_current_trace_context() |
| 450 | + if parent_trace_ctx is not None: |
| 451 | + req.parentTraceContext.CopyFrom(parent_trace_ctx) |
| 452 | + |
| 453 | + self._logger.info(f"Starting new '{req.name}' instance with ID = '{req.instanceId}'.") |
| 454 | + res: pb.CreateInstanceResponse = await self._stub.StartInstance(req) |
| 455 | + return res.instanceId |
429 | 456 |
|
430 | 457 | async def get_orchestration_state(self, instance_id: str, *, |
431 | 458 | fetch_payloads: bool = True) -> Optional[OrchestrationState]: |
@@ -487,10 +514,10 @@ async def wait_for_orchestration_completion(self, instance_id: str, *, |
487 | 514 |
|
488 | 515 | async def raise_orchestration_event(self, instance_id: str, event_name: str, *, |
489 | 516 | data: Optional[Any] = None) -> None: |
490 | | - req = build_raise_event_req(instance_id, event_name, data) |
491 | | - |
492 | | - self._logger.info(f"Raising event '{event_name}' for instance '{instance_id}'.") |
493 | | - await self._stub.RaiseEvent(req) |
| 517 | + with tracing.start_raise_event_span(event_name, instance_id): |
| 518 | + req = build_raise_event_req(instance_id, event_name, data) |
| 519 | + self._logger.info(f"Raising event '{event_name}' for instance '{instance_id}'.") |
| 520 | + await self._stub.RaiseEvent(req) |
494 | 521 |
|
495 | 522 | async def terminate_orchestration(self, instance_id: str, *, |
496 | 523 | output: Optional[Any] = None, |
|
0 commit comments