Repository navigation
Make the Lean service safe for concurrent checks of one project - #21
Conversation
Add a test that exercises the lean server under concurrent requests to verify it handles parallel load correctly. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
Moved the package staging and module build into a build_package helper so the elaborate path no longer inlines both steps. This keeps the build sequence in one place and makes it reusable by other callers. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
Staging and compiling a project's modules now run under a per-project lock so concurrent requests for the same project build one at a time while different projects still build in parallel. Each olean and ilean is written to a temporary file and renamed into place only after Lean succeeds, so a failed or timed-out compile can no longer leave a half-written olean that stale would mistake for fresh. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
The build step now checks that a temporary output file exists before replacing the final artifact, avoiding a crash when a module produces no output. The concurrency test was tidied to read files through a helper. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Tiny Sweeper reviewReviewed head: Verdict: Ready for maintainer review · Priority: none Diagnostics and supporting detailsFull summaryPull request purpose (title): Make the Lean service safe for concurrent checks of one project. Tiny Sweeper completed its review; deterministic results follow. Review snapshot
Completeness: Complete What changedA new `project_lock` in build.py keys a per-realpath threading.Lock, and a new `server.build_package` holds it across staging (`ensure_package`) and `build_modules`, with the lock released before elaboration. `build_modules` now compiles to `.tmp` files and `os.replace`s them into place, removing temporaries in a `finally`. A new test module, test_server_concurrency.py, exercises serialisation, restaging under a compile, parallel projects, and cleanup after failed and timed-out compiles. README and docstrings describe the behavior. Features
Tests
FindingsNo active actionable findings. Before mergeNone. Agent review detailscritique
security
tests
commits
description
Evidence and run details
|
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Caution Review failedThe pull request is closed. Walkthrough
Merge Risk:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 135bb8179b
ℹ️ 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".
Summary
`/check` requests for files of the same project could compile the same stale module at once, both writing one `.olean`/`.ilean`, and a reader could load a half-written olean. A restage could also rewrite sources under a build in progress (`STAGING` only serialised staging against staging). The rsi-ralph scorer will issue about 4 concurrent `lean_check` calls per candidate, so this has to be safe.
Fix: staging and `build_modules` now run together under a per-project lock (`build.project_lock`, keyed by the real path of the project's `lean/` dir) in a new `server.build_package`. Same-project requests build serially; different projects take different locks and still build in parallel. Elaboration after the build is outside the lock. Oleans are also written atomically (compile to `*.tmp`, then `os.replace`), so a failed or timed-out compile leaves no partial olean that `stale` would treat as fresh.
Related issue
None.
API or behavior changes
None to the HTTP API. Locks are per process; one service per builds dir and projects volume.
Validation
Tests
`docker/lean/test_server_concurrency.py`, written first and confirmed failing against the unlocked code (5 of 6 failed; the different-projects test passes both before and after, as it should):
No Lean needed: a fake `run` records overlapping compiles.
Documentation
`docker/lean/README.md` (new "Concurrent checks" section) and the `server.py` and `build.py` docstrings.
Checklist
Co-authored-by: Medulla medulla@tinyhumans.ai
Summary by CodeRabbit
Performance
Reliability