Skip to content

Conversation

@srbh777
Copy link

@srbh777 srbh777 commented Jan 30, 2026

Desktop fix (for PR description)

Problem

  • FsManager.updateEnvironment(id, patch) can be invoked concurrently for the same environment (e.g. rename fired twice quickly, or multiple UI surfaces triggering updates close together).
  • In local-file mode, renaming is implemented as an actual filesystem move: fs.rename(oldPath, newPath).
  • When two updates race:
    • both resolve the same oldPath via fileIndex.getPath(id)
    • both attempt fs.rename(oldPath, newPathX)
    • the first one succeeds and moves the file
    • the second one runs with the now-missing oldPath and throws ENOENT

Fix

  • Added a per-(workspace, environmentId) async lock in requestly-desktop-app so updates for the same entity are serialized.
  • Implementation details:
    • File: src/renderer/actions/local-sync/fs-manager.ts
    • Introduced a module-level updateLocks: Map<string, Promise<unknown>>
    • Added withUpdateLock(key, fn) helper that:
      • chains the new operation onto any previous promise for the same key (even if the previous one failed)
      • removes the key from the map when the chained operation completes
    • Wrapped FsManager.updateEnvironment() body in withUpdateLock(lockKey, async () => { ...existing logic... })
    • Lock key is: ${this.rootPath}::env::${id} so:
      • updates for different workspaces don’t block each other
      • updates for different environments don’t block each other
      • only the same environment is serialized

Why this is safe

  • This does not change the update semantics; it only prevents concurrent execution for the same target.
  • It specifically prevents concurrent rename/write operations from using a stale oldPath, eliminating the ENOENT race.
  • Other operations (different env ids / different workspaces) still run concurrently.

Result

  • Rapid successive renames and overlapping environment updates no longer fail with ENOENT, because the filesystem rename and fileIndex updates happen in a deterministic sequence.

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced local environment synchronization stability by resolving concurrent update race conditions that could cause errors during simultaneous environment modifications.

✏️ Tip: You can customize this high-level summary in your review settings.

@linear
Copy link

linear bot commented Jan 30, 2026

@coderabbitai
Copy link

coderabbitai bot commented Jan 30, 2026

Walkthrough

This change adds a per-key update locking mechanism to fs-manager.ts to serialize environment updates and prevent ENOENT race conditions. A global updateLocks map and withUpdateLock helper function are introduced to ensure only one update executes at a time for a given environment (identified by root path and environment ID). The locking wraps updateEnvironment calls while parsing, validation, writing, and result-returning logic remains functionally unchanged.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • iostreamer-X
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding serialization of environment updates to prevent race conditions, which matches the core objective of the PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch PLAT-73

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants