Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

java.nio.file.WatchService is missing events sometimes #277

Closed
Zomono opened this issue Oct 12, 2023 · 3 comments
Closed

java.nio.file.WatchService is missing events sometimes #277

Zomono opened this issue Oct 12, 2023 · 3 comments
Assignees
Labels
P2 type=defect Bug, not working as expected

Comments

@Zomono
Copy link

Zomono commented Oct 12, 2023

Hi,
thanks for your work on this great library. It makes a lot of my unit test easy to write and very fast!
Yesterday, I tried to use JimFS for a Class that uses the java.nio.file.WatchService
I registered it using

pathFromJimFs.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_CREATE);

In the test I just added one file into the watched directory and wait for the create event to happen.
The problem is, that sometimes file changes are not detected (no event).
And I may already found the reason for it. At

jimfs-1.3.0-sources.jar!/com/google/common/jimfs/PollingWatchService.java:243

JimFS detects changes by comparing the timestamps of a modification with the previous one and it does it only with milliseconds precision. If the test runs to quickly so that the new modification happens in the same millisecond, no event will be pushed.
If I modify my test to sleep for 1ms before adding/changing files, the problem no longer appears.

My system: Ubuntu 22.04
Test-Runner: JUnit 5
JimFSConfiguration:

Jimfs.newFileSystem(Configuration.unix().toBuilder()
    .setAttributeViews("basic", "owner", "posix", "unix")
    .setWatchServiceConfiguration(WatchServiceConfiguration.polling(1, TimeUnit.MILLISECONDS))
    .build());

If you need any more information, please let me know.

@webfolderio
Copy link

@Zomono,

I've encountered similar issues in other projects due to millisecond precision in event detection. Your observation about the rapid succession of events within the same millisecond seems spot on. A potential solution might be to use a more granular timestamp, such as nanoseconds, or incorporate a short buffer mechanism to account for rapid changes.

Your workaround with the 1ms sleep is a good short-term fix, but it might be beneficial for the library to handle such scenarios natively.

@kluever kluever added type=defect Bug, not working as expected P2 labels Oct 23, 2023
@kluever
Copy link
Member

kluever commented Oct 23, 2023

I think this is probably blocked on jimfs being able to use a better time source than System.currentTimeMillis(). See the comment in com/google/common/jimfs/SystemFileTimeSource.java:

// If/when Jimfs requires Java 8 this should use the FileTime factory that takes an Instant as
// that has the potential to be more precise. At that point, we should make a similar change to
// FakeFileTimeSource.

We could try to get a bit fancy (cough hacky cough) here and use a reflective check to see if java.time is available like I did in protobuf's Timestamps.java

@cgdecker
Copy link
Member

Hey, a few thoughts:

  1. Actually, as of the latest release (1.3.0) there's a workaround you could use now: configuration.setFileTimeSource(FileTimeSource) would allow you to configure Jimfs to use an implementation of FileTimeSource that returns FileTime.from(Instant.now()).
  2. Also, though, Jimfs requires a minimum of Java 8 now anyway so we could just change the SystemFileTimeSource implementation to always use the Instant version.
  3. I honestly can't remember but it's possible the current behavior is intentional because it (at the time at least) more closely matched what I saw happening with real file systems; I know, for example, that's why I used a polling implementation rather than something that would otherwise make more sense for an in-memory file system, like one where events are propagated directly to the watch service. Like I said though, I don't remember about this particular aspect and my comments at least don't make it sound like that.

copybara-service bot pushed a commit that referenced this issue Oct 23, 2023
Fixes #277

RELNOTES=n/a
PiperOrigin-RevId: 575796090
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P2 type=defect Bug, not working as expected
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants