zola icon indicating copy to clipboard operation
zola copied to clipboard

Fix hot reloading for `config.toml` in `zola serve` on Linux

Open iamorphen opened this issue 1 year ago • 4 comments

Introduction

Fixes #2266 , alternative to #2269 which appears to be stalled and has a large diff against next. In particular, this fixes hot reloading for changes made to config.toml via the caching strategy used by editors such as vim on Linux. At the time of this writing, changes written to config.toml via at least vim and neovim on Linux are not noticed at all by zola serve.

Code changes

  1. Watch config.toml's containing folder--not config.toml directly--for changes. See Details for why.
  2. Each item to watch tracks whether to watch it recursively.
  3. Ignore changes to files peer to config.toml, assuming that all other files we care about are nested more deeply than the config file. This is the case at the time of this writing, and the Zola docs suggest that config.toml is the only top-level file we watch in a zola project.
  4. When announcing the files we're watching, replace the config file parent directory with the config file name to not confuse the end user, since we ignore all ordinary files peer to config.toml.

Details

Editors such as vi, vim, and neovim cache changes to swap files. When a user wants to write to the original file, such editors may delete the original file and replace it with the swap file. This changes the inode of the "original" file. The file-watching strategy on Linux is inotify which watches for changes via inodes, not file names. So when an editor like vim deletes the file we're watching, we lose event information on that file after the final delete event. If we instead watch the owning directory, we can observe events on all file changes and with some filtering pretend like we're watching the same config.toml file all along.

The reason this bug is not observed on macOS is because macOS uses FSEvents to watch for file system changes. FSEvents monitors on the directory level. The change here makes behavior on Linux approximate that of FSEvents.

zola uses Notify v4, and notify::watcher returns a RecommendedWatcher. The recommended watcher on macOS is FsEventWatcher whereas it is INotifyWatcher on Linux.

Testing

Due to where the ignore logic is done in serve.rs:serve, we can't really extend the tests in the same module to check this feature.

I have manually checked zola serve on Linux and macOS by editing config.toml and theme files and observing hot reloading. I also edited theme.toml at the top-level of a zola project, and such changes were correctly ignored.

I don't have a Windows platform to test on.

UI

Due to the watch list remapping, zola serve still announces the following to the end user (note config.toml even though we watch the parent directory).

Listening for changes in /foo/bar/{config.toml,content,static,templates}
Press Ctrl+C to stop

iamorphen avatar May 16 '24 11:05 iamorphen

CI shows a compilation error in notify on Windows. I can't personally debug that locally. It seems to be a notify-internal issue. I could try to bump the notify version zola uses and see if that fixes the problem. I can try that in a separate draft MR.

iamorphen avatar May 16 '24 11:05 iamorphen

For notify, there's https://github.com/getzola/zola/issues/2077 and it looks like it's on v6 now. We will need to upgrade before the next release anyway so if you have time that would be great

Keats avatar May 16 '24 18:05 Keats

My hacked up experiment with notify-debouncer-full in #2499 passed all CI. I'll see about making the implementation production-worthy.

iamorphen avatar May 17 '24 03:05 iamorphen

For posterity, the reason the Windows build issue popped up seems to be because libc in the CI run is 0.2.154 whereas other successful CI runs (ex) use 0.2.151. The versions of winapi and notify otherwise seem identical across recent CI runs. I found master to use 0.2.151, but something in next moved us to 0.2.154.

iamorphen avatar May 19 '24 06:05 iamorphen

I rebased and re-tested locally on Linux. I'm just one data point, but all's working on my end.

iamorphen avatar May 24 '24 01:05 iamorphen

Works on mac as well

Keats avatar May 24 '24 18:05 Keats

Thanks!

Keats avatar May 24 '24 18:05 Keats

Sorry, was away for a bit, just wanted to say thank you also for your time here!

iamorphen avatar May 31 '24 00:05 iamorphen