From 23453cb4f2ba10b8aecf356424345c783bdf3071 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Wed, 2 Sep 2026 19:09:27 -0700 Subject: [PATCH] refactor(gateway): kanban dispatcher passes settings via asdict; artifact path collection without closure --- gateway/kanban_watchers.py | 28 +++++++++------------------ gateway/kanban_watchers_dispatcher.py | 12 +++--------- 2 files changed, 12 insertions(+), 28 deletions(-) diff --git a/gateway/kanban_watchers.py b/gateway/kanban_watchers.py index 005d7e96b4..ce081bd000 100644 --- a/gateway/kanban_watchers.py +++ b/gateway/kanban_watchers.py @@ -144,31 +144,21 @@ class GatewayKanbanWatchersMixin: deduplicated, missing files are skipped (may be mentioned for reference only), and upload errors are logged, never raised. """ - candidates: list[str] = [] - seen: set[str] = set() - - def _add(path: str) -> None: - if not path: - return - expanded = os.path.expanduser(path) - if expanded in seen or not os.path.isfile(expanded): - return - seen.add(expanded) - candidates.append(expanded) - + raw_paths: list[str] = [] if isinstance(event_payload, dict): raw = event_payload.get("artifacts") if isinstance(raw, (list, tuple)): - for item in raw: - if isinstance(item, str): - _add(item) + raw_paths += [item for item in raw if isinstance(item, str)] summary = event_payload.get("summary") if isinstance(summary, str) and summary: - for p in adapter.extract_local_files(summary)[0]: - _add(p) + raw_paths += adapter.extract_local_files(summary)[0] if task is not None and getattr(task, "result", None): - for p in adapter.extract_local_files(str(task.result))[0]: - _add(p) + raw_paths += adapter.extract_local_files(str(task.result))[0] + candidates: list[str] = [] + for path in raw_paths: + expanded = os.path.expanduser(path) if path else "" + if expanded and expanded not in candidates and os.path.isfile(expanded): + candidates.append(expanded) if not candidates: return diff --git a/gateway/kanban_watchers_dispatcher.py b/gateway/kanban_watchers_dispatcher.py index fceba657e5..9dda4cf3c0 100644 --- a/gateway/kanban_watchers_dispatcher.py +++ b/gateway/kanban_watchers_dispatcher.py @@ -11,7 +11,7 @@ import contextlib import os import sqlite3 import time -from dataclasses import dataclass +from dataclasses import asdict, dataclass from typing import Any, Optional from gateway.kanban_watchers_common import _board_slugs, _positive_int_setting, logger @@ -186,18 +186,12 @@ class _KanbanDispatcher: fingerprint = self.board_db_fingerprint(slug) if not self._quarantine_lifted(slug, fingerprint): return None - s = self.settings + kwargs = {k: v for k, v in asdict(self.settings).items() if k != "interval"} try: # No explicit init_db(): connect() runs the migration once per # process (see the matching note in the notifier collector). conn = self.kb.connect(board=slug) - return self.kb.dispatch_once( - conn, board=slug, max_spawn=s.max_spawn, max_in_progress=s.max_in_progress, - failure_limit=s.failure_limit, stale_timeout_seconds=s.stale_timeout_seconds, - default_assignee=s.default_assignee, - max_in_progress_per_profile=s.max_in_progress_per_profile, - reconcile_orphans=s.reconcile_orphans, - ) + return self.kb.dispatch_once(conn, board=slug, **kwargs) except Exception as exc: if self.is_corrupt_board_db_error(exc): self.disabled_corrupt_boards[slug] = (fingerprint, time.monotonic())