[Development] QFileSystemWatcher and Recursive Monitoring (Arvid E. Picciani)

logic.cpp logic.cpp at gmail.com
Sun Jul 22 12:09:10 CEST 2012


BH

Hey'all, Thanks for the feedback.

I think we can still make everything work inside one single class, either
QFileSystemWatcher or perhaps a new class if we don't want to break QFSW too
much. We'll do this à la "Graceful Degradation".

Before I explain, consider also the fact that - as Arvid mentioned - QFSW itself
doesn't (yet) offer fully granular notifications as to what precisely changed.
All we have is fileChanged(), directoryChanged(), fileModified(), pathCreated()
and pathDeleted() (the last three are w00t's patch in review
<https://codereview.qt-project.org/#change,19274> ). I propose that Qt should
offer more awesomely useful notifications about file-system changes. This can be
acheived either by creating even moar signals, or perhaps in a different way -
as will be explained.

Here's how it'll work;

Windows:
	With ReadDirectoryChangesW we have single-item monitoring, recursive
	monitoring, and we can get this cool notification "Renamed from" + "Renamed
	to" which QFSW doesn't offer ATM.

Linux/X11:
	With inotify we have single-item monitoring, recursive monitoring (gulp),
	and we have even awesomer signals than windows, like "Moved from" + "Moved
	to".

Mac OS X:
	We'll use kqueue for single-item monitoring (addPath() for "A"-category use
	cases) and we'll use FSEvents for recursive monitoring (addPathRecursive()
	for "B" use cases).

>From what I gather, in Qt we don't like to have actual functions/signals that
behave differently (or are altogether ignored) on different platforms. So
instead of having many different signals in the file-system monitor class which
won't even be emitted on some platforms (Mac), how about we emit just ONE signal
that will pass to the user 1) a path string and 2) an enum flag about what excly
happened (akin to inotify events enum <http://en.wikipedia.org/wiki/Inotify> ).
This ensures consistent behavior cross all platforms, there's always a path and
enum passed with the signal. The only difference will be in the granularity of
info that the path/enum-flag will have, offering the most info available on the
platform "gracefully degrading" as needed.

So for example, for a single file watch on "foo/bar/baz.txt":

Windows: "C:\foo\bar\baz.txt" QFSW_DELETED
Linux/X11: "/foo/bar/baz.txt" QFSW_DELETED
Mac (kqueue): "/foo/bar/baz.txt" QFSW_DELETED <- no degradation

And for a recursive watch on the "foo/" directory:

Windows: "C:\foo\bar\baz.txt" QFSW_DELETED
Linux/X11: "/foo/bar/baz.txt" QFSW_DELETED
Mac (FSEvents): "/foo/bar/" QFSW_DIR_CHANGED <- graceful degradation

Notice how on Mac we get notified on the exact leaf-most folder where the event
happened, and that the event is always just "something changed here".

This will all be very clearly documented in detail, so users will know that on
Mac they need to do further investigations when using recursive. They'll also
learn about the limits of single-item monitoring (256 kqueue file descriptors).
Alternatively we can expose a capabilities() function which can dynamically tell
the user about the API's platform limitations (granularity of notification info,
file-descriptor count limitations on Mac, etc).

Bottom line: Doing it like this will successfully exploit the capabilities of
all platforms' file-system monitoring facilities to their max, and will safely
cover most if not all use case scenarios.

A.k.a. what Qt is all about :)

-regedit


P.S. I was made aware by a smart fellow in #qt-labs that FSEvents began offering
file-level notifications since OS X Lion+. Seeing as Qt must support older
versions, the idea of a capabilities() function sounds more interesting here (so
Lion+ can already begin taking advantage of file-level events).



More information about the Development mailing list