The documentation for the overflow states:
OVERFLOW – Indicates that events might have been lost or discarded.
It does not say under what circumstance should I expect event to be lost or discarded? At first I thought it would be a result of writing a lot of files very fast to the folder. I created a few thousand files with zero size and moved them to a monitored directory. No OVERFLOW.
What am I missing?
Minimal example that generates overflows
Just create the files after watcherService.register
and before watcherService.take
.
Invoke with:
java Overflow 256
to control the number of events.
Java 7 and Ubuntu 14.04 maxes out at 512 events.
Each time there was an overflow, only a single event was returned by pollEvents()
, but this is not very clearly specified on the Javadoc.
I find it weird that this limit is so small, considering that:
sysctl fs.inotify.max_user_watches
is 524288
inotify
on Linux: http://hg.openjdk.java.net/jdk7u/jdk7u60/jdk/file/33c1eee28403/src/solaris/native/sun/nio/fs/LinuxWatchService.c#l36
The code:
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchService;
import java.util.List;
public class Overflow {
@SuppressWarnings("unchecked")
static <T> WatchEvent<T> cast(WatchEvent<?> event) {
return (WatchEvent<T>)event;
}
public static void main(final String[] args) throws InterruptedException, IOException {
int nfiles;
if (args.length > 0)
nfiles = Integer.parseInt(args[0]);
else
nfiles = 10_000;
Path directory = Files.createTempDirectory("watch-service-overflow");
final WatchService watchService = FileSystems.getDefault().newWatchService();
directory.register(
watchService,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE);
final Path p = directory.resolve(Paths.get("Hello World!"));
for (int i = 0; i < nfiles; i++) {
Files.createFile(p);
Files.delete(p);
}
List<WatchEvent<?>> events = watchService.take().pollEvents();
for (final WatchEvent<?> event : events) {
if (event.kind() == StandardWatchEventKinds.OVERFLOW) {
System.out.println("Overflow.");
System.out.println("Number of events: " + events.size());
return;
}
}
System.out.println("No overflow.");
Files.delete(directory);
}
}
"File systems may report events faster than they can be retrieved or processed and an implementation may impose an unspecified limit on the number of events that it may accumulate. Where an implementation knowingly discards events then it arranges for the key's pollEvents method to return an element with an event type of OVERFLOW. This event can be used by the consumer as a trigger to re-examine the state of the object."
From JavaDoc.
See also Steven C's answer. His point about unconsumed events makes the difference, I think.
I created a few thousand files with zero size and moved them to a monitored directory. No OVERFLOW.
Presumably, you are consuming the events in parallel with creating them. If you want to trigger an overflow, try pausing the consumption of events, generating lots of them (as above) and then resuming consumption. There is bound to be a limit on the number of unconsumed events that the operating system can buffer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With