WatchService questions

John Hendrikx hjohn at xs4all.nl
Sat Dec 5 04:18:08 PST 2009


Hi, I'm making good use of the WatchService for a file manager type 
program, and I'm finding that I have some questions that I cannot glean 
from the documentation or examples.

Let me give some quick background.  I'm using the WatchService to 
monitor a directory.  This directory sometimes is heavily modified (like 
deleting 7000 files, copying lots of files etc).  I've been having some 
trouble during testing with high CPU use resulting from lots and lots of 
updates from the WatchService, which lead me to these questions.

1) How should OVERFLOW be handled?  If it occurs, will it be the first 
event returned from pollEvents, and if so, can I safely reset the key 
after handling it?  If not the first event, would it be wise to scan for 
an OVERFLOW and then just reset the key?

2) Is it possible to keep a directory sync'd using the WatchService or 
are there races/timing issues that may cause updates to be lost?  Like 
for example, when I handle OVERFLOW (by re-reading the directory), what 
would be the correct way of making sure I'm not missing any updates?  
Currently I re-read the directory before resetting the key again, is 
this sufficient?  In other words, can I rely on the WatchService to keep 
my directory up-to-date or should I periodically re-read the directory?

3) Is there any way to throttle the amount of updates?  Currently I just 
delay for 1 second in the loop that keeps an eye on the WatchService -- 
without this, the handling of all the events (during Copy or Deletes) 
consumes so much CPU that some threads (Swing updates) are starved for 
CPU time.  This may also be my own slow handling of the incoming events, 
but I did notice that ENTRY_MODIFY can be send a lot during copying 
(once for every few kB copied it seems, which makes for a fun live 
update display...).  Are ENTRY_MODIFY events consolidated if I simply 
donot poll as often?  Could I throttle only ENTRY_MODIFY?

This is an outline of the code I currently use:

for(;;) {
  Thread.sleep(1000);
  final WatchKey key = watchService.take();
 
  try {
    EventQueue.invokeAndWait(new Runnable() {
      @Override
      public void run() {
        synchronized(listModel) {
          if(key.isValid()) {
            for(WatchEvent<?> event : key.pollEvents()) {
              // Handle the events -- sometimes > dozens/second
            }
          }
        }
      }
    });
  }
  catch(...) {}

  key.reset();
}


I suspect my problem is that I'm handling most of the events on the 
Swing dispatch thread, and I'm underestimating how much time that is 
taking me (and how much events are getting generated).  It functions as 
intended when copying large files, but when many small files are 
involved, the load is so great that Swing can't do it's regular updates 
any more.

Thanks for any insights,
John


More information about the nio-dev mailing list