Repository navigation
fix: prevent concurrent memory hygiene passes and Windows file lock errors - #535
Conversation
…rrors (#495) The heartbeat system spawns hygiene passes via tokio::spawn on every tick, creating a TOCTOU race where multiple tasks read the state file before any saves, causing all to execute concurrently. On Windows this also triggers OS error 1224 (file locked by memory-mapped section) when multiple tasks call std::fs::write on the same file. Three fixes: - AtomicBool guard (RUNNING + RunningGuard RAII) ensures only one hygiene pass runs at a time - State file is saved before cleanup (not after) to claim the cadence window early and close the TOCTOU race - Atomic file write (write to .tmp then rename) avoids Windows file-locking errors from concurrent writers Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request addresses issues related to concurrent execution of memory hygiene passes, specifically preventing race conditions and resolving Windows file-locking errors. The changes ensure that hygiene operations are serialized and state updates are handled robustly, improving the reliability and stability of the system's cleanup routines. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request effectively addresses a concurrency issue in the memory hygiene system. The introduction of an AtomicBool with an RAII guard is a robust solution to prevent concurrent hygiene passes, and the switch to an atomic file write pattern correctly resolves potential file locking errors on Windows. The logic is sound, the changes are well-documented, and the new regression tests are a valuable addition that verifies the fixes. I have one minor suggestion to improve the new test's robustness against parallel execution.
|
|
||
| /// Regression test for issue #495: concurrent hygiene passes should be | ||
| /// serialized by the AtomicBool guard. | ||
| #[test] |
There was a problem hiding this comment.
This test modifies the global static RUNNING. Since cargo test runs tests in parallel by default, this could lead to flaky tests if other tests that also interact with the hygiene system are added in the future. To ensure this test is robust and doesn't interfere with other tests, it's best to serialize access to the shared global state. You can achieve this by adding a static Mutex at the tests module level and acquiring a lock at the beginning of this test.
There was a problem hiding this comment.
Addressed in 6a1a0a4. Added a static RUNNING_TESTS: Mutex<()> to the test module and the running_guard_prevents_reentry test now acquires it before touching the global RUNNING AtomicBool.
Address PR review feedback: the running_guard_prevents_reentry test manipulates a global static AtomicBool, which could cause flaky failures if future tests also touch it and run in parallel. A test-only Mutex ensures serialization. [skip-regression-check] Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rrors (nearai#535) * fix: prevent concurrent memory hygiene passes and Windows file lock errors (nearai#495) The heartbeat system spawns hygiene passes via tokio::spawn on every tick, creating a TOCTOU race where multiple tasks read the state file before any saves, causing all to execute concurrently. On Windows this also triggers OS error 1224 (file locked by memory-mapped section) when multiple tasks call std::fs::write on the same file. Three fixes: - AtomicBool guard (RUNNING + RunningGuard RAII) ensures only one hygiene pass runs at a time - State file is saved before cleanup (not after) to claim the cadence window early and close the TOCTOU race - Atomic file write (write to .tmp then rename) avoids Windows file-locking errors from concurrent writers Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: add Mutex to serialize tests touching global RUNNING AtomicBool Address PR review feedback: the running_guard_prevents_reentry test manipulates a global static AtomicBool, which could cause flaky failures if future tests also touch it and run in parallel. A test-only Mutex ensures serialization. [skip-regression-check] Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Fixes #495.
The heartbeat system spawns
run_if_due()viatokio::spawnon every tick (default 30 min), creating a TOCTOU race where multiple tasks read the state file before any saves it, causing all to execute concurrently. On Windows this also triggers OS error 1224 when multiple tasks write the same file simultaneously.Three fixes:
RUNNING+RunningGuardRAII) ensures only one hygiene pass runs at a time.json.tmp, thenrename) avoids Windows file-locking errors from concurrent writersTest plan
cargo test hygiene-- 8 passed (including 2 new regression tests)cargo clippy --all --all-features-- zero warningsGenerated with Claude Code