abey79 / vsketch

Generative plotter art environment for Python
https://vsketch.readthedocs.io/en/latest/
Other
493 stars 50 forks source link

Auto refresh change detection fails #415

Open verdog opened 9 months ago

verdog commented 9 months ago

I'm observing this on Linux.

Adding some print statements to the file watcher thread:

class FileWatcherThread(QThread):
    sketchFileChanged = Signal()

    def __init__(self, path: pathlib.Path, *args: Any, **kwargs: Any):
        super().__init__(*args, **kwargs)
        self._path = path
        self._stop = False

    def is_set(self) -> bool:
        return self.isInterruptionRequested()

    def run(self):
        print(f"starting file watch: {self._path}")
        for changes in watchfiles.watch(self._path, stop_event=self):
            # noinspection PyTypeChecker
            for change in changes:
                print(change)
                if (
                    pathlib.Path(change[1]) == self._path
                    and change[0] == watchfiles.Change.modified
                ):
                    # noinspection PyUnresolvedReferences
                    self.sketchFileChanged.emit()

When I edit a sketch in neovim, I see this:

(vsketch-py3.11) [josh@turbine vsketch]$ vsk run examples/noise_plotloop/sketch_noise_plotloop.py 
Running sketch: /home/josh/vsketch/vsketch/examples/noise_plotloop/sketch_noise_plotloop.py
starting file watch: /home/josh/vsketch/vsketch/examples/noise_plotloop/sketch_noise_plotloop.py
(<Change.deleted: 3>, '/home/josh/vsketch/vsketch/examples/noise_plotloop/sketch_noise_plotloop.py')

Further changes to the file are undetected.

It seems that:

  1. Some text editors actually delete and then replace a file upon saving
  2. watchfiles removes a file from its watch list when it detects that it's been deleted

Adding force_polling=True to the watchfiles.watch(self._path, stop_event=self): line seems to fix it. Haven't tested for more than 5 minutes though.


For a fix, maybe this could be combined with #88 and a setting for polling could be added along with the setting to disable/enable file watching.

nishanthmerwin commented 8 months ago

I have the same issue when using neovim! Saving the file doesn't seem to update the viewer.

abey79 commented 8 months ago

Apparently, you can trigger the force_polling=True by setting the WATCHFILES_FORCE_POLLING environment variable. Does that fix the issue for you?

verdog commented 8 months ago

Yup that has the same effect as force_polling=True and works for me.

nishanthmerwin commented 8 months ago

This solution worked for me too!

abey79 commented 8 months ago

OK good news that there is a workaround.

This is weird though. It appears that one "correct" solution would be to catch watchfiles.Change.create as well (which would be triggered for deleted/recreated files), but from the OP it appears that it is not emitted either? Can you confirm that @verdog?

Also, could one of you please test with various watchfiles versions? Maybe an issue was introduced recently, e.g. in 0.21? With pipx install, you can run pipx inject vsketch watchfiles==0.20. I guess versions 0.18.1, 0.19, and 0.20 would be interesting to test.