Source code for gyoza.worker.execution_pipeline.pipeline

"""Pipeline implementation."""

import traceback

import httpx

from gyoza.worker.execution_pipeline.types import ExecutionContext, Step


[docs] class Pipeline: """A sequence of steps executed in order. Parameters ---------- steps : list[Step] Ordered list of steps to execute. """ def __init__(self, steps: list[Step] | None = None) -> None: self._steps: list[Step] = list(steps) if steps else []
[docs] def run(self, ctx: ExecutionContext | None = None) -> ExecutionContext: """Execute all steps in sequence. If any step raises an exception the run is marked as FAILED via the server API and the exception is re-raised so the caller can log it. The one exception is a lost connection to the server (``httpx.TransportError``), which is not reported: it says nothing about the op or its data, and a FAILED written for it ended the run on its first attempt. The attempt is left as it is instead; once the worker stops listing it, the reaper hands the run to a fresh attempt, as it does for any run its worker dropped. ``HTTPStatusError`` is a real answer from the server and still fails the run. Parameters ---------- ctx : ExecutionContext | None Shared context. Created if not provided. Returns ------- ExecutionContext The context after all steps have been applied. Raises ------ Exception Whatever exception the failing step raised. """ if ctx is None: ctx = ExecutionContext() try: for step in self._steps: ctx = step(ctx) except httpx.TransportError: raise except Exception as exc: from gyoza.client import gyoza_client # noqa: PLC0415 _MAX_MSG_LEN = 10000 msg = f"{type(exc).__name__}: {exc}\n{traceback.format_exc()}" try: gyoza_client.add_event( run_id=ctx.oprun_id, attempt=ctx.attempt, worker_id=ctx.worker_id, event_type="FAILED", msg=msg[:_MAX_MSG_LEN], payload={"error_message": f"{type(exc).__name__}: {exc}"[:500]}, ) except Exception: pass raise return ctx