Question

Is there a haskell library function to monitor a file without polling?

With polling i would do someting like this:

monitor file mtime handler = do
    threadDelay n -- sleep `n` ns
    t <- getModificationTime file
    if t > mtime
        then handler >> monitor file t handler
        else monitor file mtime handler

What I want is something like a blocking getModificationTime which will be woken up by the system. Is there something available?

I would be perfectly happy if it was available for posix systems only, but the more portable the better :-)

Edit: I know hinotify, but I'm on a Mac (that's why I mention POSIX).

Was it helpful?

Solution

The kqueue package should do this: http://hackage.haskell.org/package/kqueue

OTHER TIPS

There was a GSoC project which resulted in the fsnotify package which uses system-specific libraries, and falls back to polling. It uses hfsevents on Mac.

The Package suggested by Sjoerd Visscher works like a charm (using GHC 7.0.3 and kqueue 0.1.2.4, Mac OS X 10.6 Snow Leopard).

I compiled a quick sample using it (since I could not find API documentation, but there are some examples up on github):

import Control.Concurrent.MVar
import System.KQueue.HighLevel (watchFile, EventType, Watcher)
import System.Environment (getArgs)

watch :: MVar EventType -> FilePath -> IO Watcher
watch chan file =
    let handler ev = putMVar chan ev
    in  watchFile file handler

listen :: MVar EventType -> IO ()
listen chan = takeMVar chan >>= print >> listen chan

main :: IO ()
main = do
        args <- getArgs
        chan <- newEmptyMVar
        mapM (watch chan) args
        listen chan

This will create a little program which you can pass filepaths on as arguments and monitor these files. The Events are fed back through an MVar and read by the main thread which is basically a loop implemented by listen. The program has to be killed using ^C since it is designed to run forever.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top