Add an asynchronous background job manager - #95
Conversation
- Run long REPL operations in a bounded worker pool with serializable lifecycle snapshots.\n- Serialize mutating jobs by target resource and capture sanitized results and failures.\n- Add REPL job inspection, documentation, and concurrency regression tests.\n\nFixes #51
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a91411cd64
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| exit_code = dispatch(namespace, self.context, emit=capture) | ||
| return {"exit_code": exit_code, "output": output} |
There was a problem hiding this comment.
Mark nonzero sync jobs as failures
When gedcom sync runs in the background, dispatch() can return the sync workflow's nonzero exit code (for example when the sync parser or manifest validation returns an error) without raising. _dispatch_job then wraps that integer in a normal result, so JobManager records the job as completed with no stable error code and jobs list/show cannot distinguish a failed sync from a successful one; convert nonzero dispatch returns into a failed job snapshot instead.
AGENTS.md reference: AGENTS.md:L18-L19
Useful? React with 👍 / 👎.
| locks = [self._resource_lock(key) for key in resource_keys] | ||
| try: | ||
| for lock in locks: | ||
| lock.acquire() |
There was a problem hiding this comment.
Keep resource-lock waiters out of the worker pool
Because worker threads call lock.acquire() before the job is marked running, jobs waiting on a busy resource consume executor workers. With max_workers=2, one long job for tree.ged and one same-resource waiter occupy both workers, so a later job for other.ged cannot start until the same-resource backlog advances; that violates the intended parallelism for independent targets. Gate per-resource waiters outside the worker pool or reschedule blocked jobs instead.
Useful? React with 👍 / 👎.
Summary
jobs list/jobs show JOB_IDVerification
make test— 401 passed, 8 skippedmake lint— passedmake typecheck— passedmake security— dependency audit clean; Semgrep 1,102 rules / 64 files / 0 findingsgit diff --check— passedFixes #51