|
5 | 5 | """ |
6 | 6 |
|
7 | 7 | import asyncio |
| 8 | +import inspect |
8 | 9 | import uuid |
9 | 10 | from contextlib import nullcontext |
10 | 11 | from datetime import datetime, timedelta, timezone |
@@ -1643,6 +1644,23 @@ async def _worker(self) -> None: |
1643 | 1644 | job_id = job["id"] |
1644 | 1645 | payload = dict(job["payload"]) |
1645 | 1646 | payload["services"] = self.services |
| 1647 | + payload.setdefault("codebase_hash", job["codebase_hash"]) |
| 1648 | + # Jobs created by older clients/tests may contain only a partial |
| 1649 | + # payload. Do not invoke the strict generation coroutine with |
| 1650 | + # missing positional arguments (which otherwise leaves noisy |
| 1651 | + # retry/failure logs and can consume a worker during integration |
| 1652 | + # runs). Mark malformed durable jobs failed and continue polling. |
| 1653 | + required = ("codebase_dir", "cpg_path", "language", "container_cpg_path") |
| 1654 | + signature = inspect.signature(_generate_cpg_async) |
| 1655 | + validates_payload = not any( |
| 1656 | + parameter.kind is inspect.Parameter.VAR_KEYWORD |
| 1657 | + for parameter in signature.parameters.values() |
| 1658 | + ) |
| 1659 | + if validates_payload and any(payload.get(key) in (None, "") for key in required): |
| 1660 | + error = f"Malformed generate_cpg payload; missing one of: {', '.join(required)}" |
| 1661 | + logger.error("CPG generation job %s rejected: %s", job_id, error) |
| 1662 | + await loop.run_in_executor(None, self.store.fail_job, job_id, error) |
| 1663 | + continue |
1646 | 1664 | try: |
1647 | 1665 | await _generate_cpg_async(**payload) |
1648 | 1666 | await loop.run_in_executor(None, self.store.complete_job, job_id) |
|
0 commit comments