import java.io.Closeable;
import java.io.IOException;
+import java.nio.file.AccessDeniedException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
private static final Kind<?>[] ALL_EVENTS = { ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY };
- private static AtomicInteger threadCounter = new AtomicInteger();
+ private static AtomicInteger threadCounter = new AtomicInteger(1);
private LongConsumer consumer;
private Kind<?>[] events;
public static DirectorySizeTracker startTracker(LongConsumer sizeChangeListener) throws IOException {
DirectorySizeTracker watcher = new DirectorySizeTracker(sizeChangeListener, ALL_EVENTS);
- watcher.thread = new Thread(watcher, DirectorySizeTracker.class.getSimpleName() + threadCounter.get());
+ watcher.thread = new Thread(watcher, DirectorySizeTracker.class.getSimpleName() + "-" + threadCounter.get());
watcher.thread.start();
return watcher;
}
Path dir = trackedDirs.getRight(key);
if (dir == null) {
LOGGER.error("WatchKey not registered: " + key);
+ for (WatchEvent<?> event : key.pollEvents()) {
+ WatchEvent.Kind<?> kind = event.kind();
+ // TBD - provide example of how OVERFLOW event is handled
+ if (kind == OVERFLOW)
+ continue;
+ // Context for directory entry event is the file name of entry
+ WatchEvent<Path> evt = cast(event);
+ Path name = evt.context();
+ LOGGER.error(String.format("MISSED EVENT: %s: %s", event.kind().name(), name));
+ }
+ boolean valid = key.reset();
+ LOGGER.error("RESET KEY RETURNED: " + valid);
continue;
}
if (!entrySizes.containsKey(child)) {
untrack(child);
}
+ } catch (AccessDeniedException e) {
+ // Ignore. This can happen e.g. with temporary locked Lucene index files.
} catch (IOException ioe) {
LOGGER.error("Failed to read attribute for path " + child, ioe);
}
while (running)
processEvents();
} finally {
+ // It seems that for some reason cancelling all watch keys
+ // helps the watcher close itself. Otherwise closing the
+ // watch service seemed to get stuck easily.
+ cancelWatchKeys();
FileUtils.uncheckedClose(watcher);
}
}
+ private void cancelWatchKeys() {
+ synchronized (lock) {
+ for (WatchKey key : trackedDirs.getLeftSet()) {
+ key.cancel();
+ key.pollEvents();
+ }
+ }
+ }
+
/**
* @return total size of the tracked directories in bytes
*/
}
// public static void main(String[] args) {
-// try {
-// DirectorySizeTracker tracker = DirectorySizeTracker.startTracker(null);
-// tracker.track(Paths.get("d:/track-test"));
+// try (DirectorySizeTracker tracker = DirectorySizeTracker.startTracker(null)) {
+// tracker.track(Paths.get("d:/temp dir"));
// LOGGER.info("AFTER TRACK: Total size from " + tracker.entrySizes.size() + " files and " + tracker.trackedDirs.size() + " directories is " + tracker.getTotalSize());
// Thread.sleep(2000);
// //tracker.untrack(Paths.get("d:/track-test"));