Both the single-run path and the campaign scheduler drove long-lived asyncio tasks through their own duplicated _tasks/_cancel_events dicts and shutdown loops. Collapse them into one deep TaskRegistry module, instantiated as run_registry and campaign_registry. launch() creates the cancel event before the task (so a cancel during startup is never lost), wires done-callback cleanup, and is idempotent per id; this makes runs.py's hard-cancel fallback provably dead, so it is removed. App shutdown now gracefully stops in-flight runs too, not just campaigns. |
||
|---|---|---|
| .. | ||
| __init__.py | ||
| test_auth_api.py | ||
| test_campaign_runner.py | ||
| test_campaign_scheduler_loop.py | ||
| test_campaigns_api.py | ||
| test_files_api.py | ||
| test_model_config_migration.py | ||
| test_model_configs_api.py | ||
| test_reports_api.py | ||
| test_runs_api.py | ||
| test_scenario_version_migration.py | ||
| test_scenarios_api.py | ||
| test_stats_api.py | ||