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