New API
Thinking of a new API for version 0.4.
The current callback based API has several weaknesses, including silently dropping exceptions from the user's callback code which several users has noticed.
A new API could look something like this:
inotify :: IO INotify
addInotify :: INotify -> [EventVariety] -> FilePath -> IO WatchDescriptor
readEvents :: INotify -> IO [Event]
It'd be without background threads, without channels, thus much simpler. Event overflow would be left to the linux kernel.
The problem is this requires polling in the client application. STM based queues would give you the best of both worlds (although adds more dependencies).
The application can solve it in whatever way it wishes if we provide the building blocks.
One other building block I would add is waitForEvent :: INotify -> IO Event. This way instead of an application repeatedly calling readEvent waiting for a new Event to pop up (which would both consume unnecessary resources and be slower) they could just call waitForEvent to, well, wait for an Event.
(Actually, if we want to go for minimalism, all you need is waitForEvent :: INotify -> IO Event and noBlockEvent :: INotify -> Maybe Event (and define readEvents in terms of it) (and you need inotify and addInotify of course).)
A lot of different concurrency mechanisms (Async, STM, etc...) would benefit from this addition.
It wouldn't be efficient to only read a single event. For performance reasons they should be read in batch. It's also essential to wait until there is enough events to read. More details here; http://www.serpentine.com/blog/2008/01/04/why-you-should-not-use-pyinotify/
Well, some sort of blocking call would be useful. Maybe waitFotEvents :: INotify -> n -> [Event]? Or have a cache of events, and waitEvent just takes off the top event (if available).
Looks like you're describing readEvents in the top post.
Does readEvents block until events are ready, or does it return the empty list if there are no events?
At least on Linux it'd block until something is available, and then return that. It won't be a lot, which is why there should be a threshold before reading.
Ah, okay. (Then I would recommend making a nonblocking version of readEvents. Note that readEventsNoBlock would still wait for thresholds and such, it just that if there aren't events (either because there really are no events, or because we do not want to check for them yet), it yields [].) It would be more efficient to put this in the library I think than to make the user check for it.)