Skip to content

Watch mode (Linux): deleting the watched root or recreating a directory within ~1 ms loses observation #1077

Description

@elucid

What happened?

On Linux (chokidar backend), two directory-lifecycle sequences leave the tree unobserved until the next reload. Both reproduce identically before and after #1076, so they are pre-existing.

  1. Deleting the watched root itself (e.g. rm -rf the repo checkout dir and recreate it, or a tool that replaces the directory atomically). After the root is recreated, file changes under it produce no events. Reproduced with a 100 ms gap between delete and recreate.
  2. Recreating a directory within ~1 ms of deleting it (rm -rf dir && mkdir -p dir/sub in one shell command; some build tools do this). Subsequent writes under it are sometimes not observed. Gaps of ≥10 ms recover reliably.

Ordinary delete-then-recreate with a realistic gap recovers (covered by observer.fs.test.ts since #1076).

Evidence

Found by an adversarial probe during review of #1076: five cycles each on the previous main (bc76a0bc) and on the batched observer, nested subtree vs root, 0/1/10/100 ms gaps. Probe and log were kept at /tmp/1063-review-churn.{ts,log} on the measurement host; the fixture spec is in test/pty/watch-start-integration.test.ts and scratch-style notes in #1063.

Possible direction

  • Root case: the observer anchors a watcher on the root's parent only when the root is missing at startup (portableTree.ts "missing-root-parent fallback"). Extending that anchor to the steady state — always watch the parent for addDir of the root — would cover the delete-and-recreate case.
  • ~1 ms recreate: likely inotify delivering IN_DELETE_SELF after the new inode already exists, so chokidar drops the path and never re-adds it. A short debounce on unlinkDir that re-stats before invalidating would probably cover it.

Priority: low. The steady-state safety signature check (every few seconds when the observer is healthy) does not run in this state either, so the user sees a stale review until they trigger a manual refresh.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions