Skip to content

[FIX] Prevent document desync between VS Code and Code Editor#111

Merged
kpal81xd merged 2 commits intomainfrom
fix/desync
Mar 2, 2026
Merged

[FIX] Prevent document desync between VS Code and Code Editor#111
kpal81xd merged 2 commits intomainfrom
fix/desync

Conversation

@kpal81xd
Copy link
Contributor

@kpal81xd kpal81xd commented Mar 2, 2026

What's Changed

Fixes document state desync when editing the same file in both VS Code and PlayCanvas Code Editor simultaneously. Three root causes addressed:

1. Save conflict — "content is newer" dialog

  • Cancel pending debounced disk sync and flush ShareDB content to disk before document.save() to prevent mtime race
  • Wait for doc.hasPending() to clear before sending doc:save: to server, matching Code Editor behavior (save.ts:144-150). Includes re-check after listener registration to prevent TOCTOU race.

2. Failed subscription cleanup and retry

  • Track subscriptions only after successful load (moved subscriptions.set() into load handler). Clean up and destroy doc on error.
  • Added resubscribe() method for retry support
  • Added _retryDocSubscription() with exponential backoff (1s, 2s, 4s, max 3 retries) replacing terminal error.set() calls
  • Guards against retry firing after unlink() and duplicate retry timers for the same document

3. Reconciliation robustness

  • Check applyEdit() return value: if edit was rejected, replace VS Code buffer from ShareDB state instead of pushing wrong state upstream
  • Log error if resync applyEdit also fails

Files Changed

File Summary
src/disk.ts Cancel debounce before save; flush to disk; check applyEdit return; improve reconciliation
src/project-manager.ts hasPending check before save; retry infrastructure for failed subscriptions
src/connections/sharedb.ts Move subscription tracking to load handler; cleanup on error/destroy; add resubscribe()

Testing

  • npm run lint — pass (prettier + eslint)
  • npm run compile — pass (TypeScript)
  • npm run pretest — pass (test compilation)
  • Manual testing: open same file in both VS Code extension and Code Editor, edit rapidly in both, verify sync remains consistent

- Cancel pending debounced sync and flush ShareDB content to disk before
  VS Code save to prevent mtime race causing "content is newer" dialog
- Wait for pending ops (hasPending) before sending doc:save to server,
  matching Code Editor behavior and preventing stale content persistence
- Track subscriptions only on successful load, clean up on error/destroy,
  and add resubscribe() for retry support
- Add exponential backoff retry for failed document subscriptions instead
  of setting a terminal error
- Check applyEdit return value in reconciliation: on failure, replace
  VS Code buffer from ShareDB state instead of pushing wrong state
@kpal81xd kpal81xd self-assigned this Mar 2, 2026
@kpal81xd kpal81xd added the bug Something isn't working label Mar 2, 2026
@kpal81xd kpal81xd merged commit 9dd3d01 into main Mar 2, 2026
3 checks passed
@kpal81xd kpal81xd deleted the fix/desync branch March 2, 2026 14:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant