Prevent duplicate cron execution and fix OpenCode validation#393
Prevent duplicate cron execution and fix OpenCode validation#393tbrandenburg wants to merge 4 commits intomainfrom
Conversation
Duplicate backend processes could each start their own cron scheduler against the same .made workspace, causing workflows and scheduled tasks to run twice silently. Changes: - Added cron PID ownership checks and stale-owner recovery before scheduler startup - Released owned PID files on shutdown and after partial startup failures - Added unit coverage for live-owner refusal, stale-owner replacement, and PID cleanup Fixes #367
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Comprehensive PR ReviewPR: #393 SummaryThis consolidation is based on the artifacts present in this run. Only Verdict:
🟠 High IssuesCron ownership claim is still race-prone across concurrent startups📍
View recommended fixdef _claim_cron_ownership() -> tuple[Path, int]:
pid_file = _get_cron_pid_file_path()
current_pid = os.getpid()
while True:
try:
fd = os.open(pid_file, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o644)
except FileExistsError:
owner_pid = _read_cron_owner_pid(pid_file)
if owner_pid is not None and owner_pid != current_pid:
if _is_process_running(owner_pid):
raise RuntimeError(
f"Cron clock already owned by live process pid={owner_pid}"
)
try:
pid_file.unlink()
except FileNotFoundError:
pass
continue
with os.fdopen(fd, "w", encoding="utf-8") as handle:
handle.write(f"{current_pid}\n")
return pid_file, current_pid🟡 Medium IssuesStartup rollback leaks a running scheduler if failure happens after
|
Fix Report: PR #393Date: 2026-04-28T00:56:24+02:00 SummaryThe review surfaced two cron startup defects in Fixes Applied
Tests Added
Docs Updated(none) Skipped Findings(none) Blocked (Could Not Fix)(none) Suggested Follow-up Issues(none) Validation
|
Summary
Changes
packages/pybackend/cron_service.pyresponse_partsandcombined_responsehandling inpackages/pybackend/agent_cli.py.opencode/package-lock.jsonwith the validation-time plugin refresh generated by OpenCode toolingValidation
make qa-quick✅ (381 passed, 1 skipped; existing sqliteResourceWarningwarnings remain)cd packages/frontend && npx tsc --noEmit✅make lint✅cd packages/frontend && npx prettier --check src vite.config.ts vitest.config.ts eslint.config.js package.json tsconfig.json tsconfig.node.json index.html && cd ../pybackend && uv run ruff format --check *.py tests/integration/test_opencode_integration.py✅cd packages/frontend && npm test && cd ../pybackend && uv run pytest -c pytest.cov.ini✅ (504 passed, 2 skipped; existing integration mark and sqlite warnings remain)make build✅Fixes #367