Skip to content

Move responsibility of disk watching for active editor into KclManager, don't watch while writing - #10305

Merged
franknoirot merged 13 commits into
mainfrom
franknoirot/9907/unwatch-while-writing
Mar 6, 2026
Merged

Move responsibility of disk watching for active editor into KclManager, don't watch while writing#10305
franknoirot merged 13 commits into
mainfrom
franknoirot/9907/unwatch-while-writing

Conversation

@franknoirot

@franknoirot franknoirot commented Mar 4, 2026

Copy link
Copy Markdown
Contributor

Fixes #9907 by supplanting the role historically played by useFileSystemWatcher with a more direct file watcher on KclManager itself, at least for the currently-active executing editor. By locating the watcher within KclManager, it can be "unwatched" just before we write to file, and resume watching after we know the file is done being written to. No need to write fancy ignoring logic.

Also introduces the ignorInitial option to our chokidar use, fixing something we thought was a bug in chokidar but was just us holding it wrong, as it was documented here https://github.com/paulmillr/chokidar?tab=readme-ov-file#path-filtering

@franknoirot
franknoirot requested a review from andrewvarga March 4, 2026 21:33
@franknoirot
franknoirot requested a review from a team as a code owner March 4, 2026 21:33
@vercel

vercel Bot commented Mar 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
modeling-app Ready Ready Preview, Comment Mar 6, 2026 8:32pm

Request Review

Comment thread e2e/playwright/debug-pane.spec.ts Outdated
@franknoirot
franknoirot force-pushed the franknoirot/9907/unwatch-while-writing branch from 5238975 to 2933ecf Compare March 5, 2026 01:29

@andrewvarga andrewvarga left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Soo, I was really pumped this would work but my experience testing this looks pretty random, definitely better but details below..
Are you on Windows or Mac? Did the issue happen for you frequently before on main (using sketch solve)?

For me first when I tried this branch locally I got a few "Reloading file from disk" messages, after which It did get much more stable, but it still happens every once in a while.

Most of the time RouteProvider/writeCausedByAppCheckedInFileTreeFileSystemWatcher makes sure the first watch event after the write is getting ignored. If this worked all the time we wouldn't need timeouts / other flags, the problem is that the file watcher event sometimes kicks in twice after a single write: when this happens the above flag doesn't help anymore and that's when the code equality check used to help and now the writingPromise check comes into play.
I'm thinking this is platform dependent, that's why I asked your OS. Sometimes a write is accompanied by metadata update which results in a second watch event.
Even for me this is super random, sometimes I'm not seeing the second watcher callback during multiple edits and then it comes back after every single edit.

To easily see how well the other safeguards perform, you can comment this line:

I think we should keep the 300ms -> 1000ms increase, becase it's a better UX during typing, but I think that may not change the current file watcher behavior (details below). I might even increase it towards 1500, 2000ms just for the typing UX because execution and related work is quite often heavy and takes time, might break out of sketch mode, etc.

Regarding the change about the new writingPromise flag: for me it is not actually effective, because of this line:

this.writingPromise.value = null

This always gets executed before the useFileSystemWatcher callback, which is triggered typically about 800-1400ms after writeFile.
(This can be tested easily by disabling the writeCausedByAppCheckedInFileTreeFileSystemWatcher flag but even without it it happens.)

So I think to effectively enable writingPromise we should increase that 30ms -> 2000ms, which sounds a bit high? I wouldn't have an issue with that but I also wouldn't have an issue with disabling the file watcher during sketch mode entirely..:)

Btw, this has a similar feel as the first fix had because it also relies on the platform specific delay it takes for a file write to result in the file watcher callback getting called, so we can even re-consider enabling that. In that PR we check the last modified timestamp of the file, which varies much less an a 50ms threshold was enough to make it stable.

TLDR:

  • I think writingPromise is currently not in use actually, the delay should be increase to about 2000ms for it to be effective. Setting it to 2000ms I'm having a difficult time reproducing the issue which looks promising
  • The other delay to 1000ms is a welcome change for better typing UX. I was wrong that this would help with the file watcher events, file write is actually driven by this 1000ms delay so independent of execution.

(This delay feels better with 1000ms, but there is still an occasional UX issue that if I stop typing for a bit -> execution starts -> that gets the updated code recast back into the editor overwriting anything I might have typed since then which can be annoying..
Steps:

  • type x = 3
  • wait 1 second so execution starts
  • start typing again, while execution is still running: x = 3 + 2
  • execution completes -> updates the code back to x = 3, making you loose "+ 2" that you just typed.
    I feel like the typing experience should be uninterrupted, which is difficult to ensure because of this update loop, but it feels like it has degraded recently.)

Let me know if a video/huddle about some of this would be helpful!

@franknoirot

Copy link
Copy Markdown
Contributor Author

Thank you for the write-up @andrewvarga! Gah, I'm on a Mac and reproducing this has been very sporadic on my device, even on main, then harder after my changes, but I definitely assume that I am not testing this carefully enough to reproduce. This line makes a lot of sense:

This always gets executed before the useFileSystemWatcher callback, which is triggered typically about 800-1400ms after writeFile.

Yeah okay I still haven't been appreciating how delayed useFileSystemWatcher is, nor how variable its delay is. That does dash my hopes of "just using the Promise returned from writeToDisk".

With regards to this section:

For me first when I tried this branch locally I got a few "Reloading file from disk" messages, after which It did get much more stable, but it still happens every once in a while.

Most of the time RouteProvider/writeCausedByAppCheckedInFileTreeFileSystemWatcher makes sure the first watch event after the write is getting ignored. If this worked all the time we wouldn't need timeouts / other flags, the problem is that the file watcher event sometimes kicks in twice after a single write: when this happens the above flag doesn't help anymore and that's when the code equality check used to help and now the writingPromise check comes into play.

I've been wondering about that actually. This comment in the code seems to suggest we think chokidar is somehow being "buggy" here, but right here in their documentation they explain that there is a flag for ignoring these initial "discovery" events before start. Do you think it's possible that these events you're seeing are the result of us not using that flag? That I'd be down to huddle on to see if your behavior goes away; I'm having trouble with repro in general here.

I have another idea that I think could still be in the spirit of "don't watch while we write", which I'll admit I really sidestepped in this PR.

  1. Never do anything from useFileSystemWatcher with respect to the current file; delete that block of code
  2. Add a literal chokidar watcher directly to KclManager that is solely responsible for the currently executing file's watcher, which is kept turned off whenever edits are being made

Maybe we could huddle about trying that?

Comment thread src/lang/KclManager.ts Outdated
this.fileWatcherKey,
this.onFileWatchEvent
)
}, 30)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting why this delay is needed but it does seem to be needed, if I remove it I can get the issue to happen occasionally.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that is weird, I just don't trust the OS layers lol. I bumped up the cooldown to be one full second, I don't think that's unreasonable for resuming FS watching after a direct edit.

@andrewvarga andrewvarga left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great find with ignoreInitial and moving the watcher into KclManager.

Tested and couldn't get it to break, looks robust!

@franknoirot

Copy link
Copy Markdown
Contributor Author

That's great! I just realized one thing I want to add before I merge this: we should clean up the watcher if the editor is ever closed (it's not really yet under the hood, but will be soon).

@franknoirot franknoirot changed the title Use a signal containing the Promise while writing to ignore file watch events Move responsibility of disk watching for active editor into KclManager, don't watch while writing Mar 6, 2026
@franknoirot
franknoirot merged commit 7ac36d3 into main Mar 6, 2026
58 checks passed
@franknoirot
franknoirot deleted the franknoirot/9907/unwatch-while-writing branch March 6, 2026 20:32
franknoirot added a commit that referenced this pull request Mar 6, 2026
…KclManager`, don't watch while writing (#10305)"

This reverts commit 7ac36d3.
franknoirot added a commit that referenced this pull request Mar 6, 2026
…r into `KclManager`, don't watch while writing (#10305)""

This reverts commit a66c669.
franknoirot added a commit that referenced this pull request Mar 6, 2026
…r into `KclManager`, don't watch while writing (#10305)""

This reverts commit a66c669.
franknoirot added a commit that referenced this pull request Mar 9, 2026
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Code editor jumps to the next line while typing

2 participants