use of java.nio.file.WatchEvent.Kind in project jetty.project by eclipse.
the class PathWatcher method run.
/**
* Forever loop.
*
* Wait for the WatchService to report some filesystem events for the
* watched paths.
*
* When an event for a path first occurs, it is subjected to a quiet time.
* Subsequent events that arrive for the same path during this quiet time are
* accumulated and the timer reset. Only when the quiet time has expired are
* the accumulated events sent. MODIFY events are handled slightly differently -
* multiple MODIFY events arriving within a quiet time are coalesced into a
* single MODIFY event. Both the accumulation of events and coalescing of MODIFY
* events reduce the number and frequency of event reporting for "noisy" files (ie
* those that are undergoing rapid change).
*
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
List<PathWatchEvent> notifiableEvents = new ArrayList<PathWatchEvent>();
// Start the java.nio watching
if (LOG.isDebugEnabled()) {
LOG.debug("Starting java.nio file watching with {}", watchService);
}
while (watchService != null && thread == Thread.currentThread()) {
WatchKey key = null;
try {
//If no pending events, wait forever for new events
if (pendingEvents.isEmpty()) {
if (NOISY_LOG.isDebugEnabled())
NOISY_LOG.debug("Waiting for take()");
key = watchService.take();
} else {
//only wait as long as the quiet time for any new events
if (NOISY_LOG.isDebugEnabled())
NOISY_LOG.debug("Waiting for poll({}, {})", updateQuietTimeDuration, updateQuietTimeUnit);
key = watchService.poll(updateQuietTimeDuration, updateQuietTimeUnit);
//If no new events its safe to process the pendings
if (key == null) {
long now = System.currentTimeMillis();
// no new event encountered.
for (Path path : new HashSet<Path>(pendingEvents.keySet())) {
PathPendingEvents pending = pendingEvents.get(path);
if (pending.isQuiet(now, updateQuietTimeDuration, updateQuietTimeUnit)) {
//so generate the events that were pent up
for (PathWatchEvent p : pending.getEvents()) {
notifiableEvents.add(p);
}
// remove from pending list
pendingEvents.remove(path);
}
}
}
}
} catch (ClosedWatchServiceException e) {
// Normal shutdown of watcher
return;
} catch (InterruptedException e) {
if (isRunning()) {
LOG.warn(e);
} else {
LOG.ignore(e);
}
return;
}
//If there was some new events to process
if (key != null) {
Config config = keys.get(key);
if (config == null) {
if (LOG.isDebugEnabled()) {
LOG.debug("WatchKey not recognized: {}", key);
}
continue;
}
for (WatchEvent<?> event : key.pollEvents()) {
@SuppressWarnings("unchecked") WatchEvent.Kind<Path> kind = (Kind<Path>) event.kind();
WatchEvent<Path> ev = cast(event);
Path name = ev.context();
Path child = config.dir.resolve(name);
if (kind == ENTRY_CREATE) {
// recursively
if (Files.isDirectory(child, LinkOption.NOFOLLOW_LINKS)) {
try {
prepareConfig(config.asSubConfig(child));
} catch (IOException e) {
LOG.warn(e);
}
} else if (config.matches(child)) {
addToPendingList(child, new PathWatchEvent(child, ev));
}
} else if (config.matches(child)) {
addToPendingList(child, new PathWatchEvent(child, ev));
}
}
}
//Send any notifications generated this pass
notifyOnPathWatchEvents(notifiableEvents);
notifiableEvents.clear();
if (key != null && !key.reset()) {
keys.remove(key);
if (keys.isEmpty()) {
// all done, no longer monitoring anything
return;
}
}
}
}
Aggregations