Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
pull_request:
branches:
- main
- improved-overflow-support-main

jobs:
test:
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/engineering/swat/watch/WatchEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@
private final Path rootPath;
private final Path relativePath;

public WatchEvent(Kind kind, Path rootPath) {
this(kind, rootPath, null);
}

Check warning on line 73 in src/main/java/engineering/swat/watch/WatchEvent.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/engineering/swat/watch/WatchEvent.java#L72-L73

Added lines #L72 - L73 were not covered by tests

public WatchEvent(Kind kind, Path rootPath, @Nullable Path relativePath) {
this.kind = kind;
this.rootPath = rootPath;
Expand Down
36 changes: 19 additions & 17 deletions src/main/java/engineering/swat/watch/impl/jdk/JDKBaseWatch.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,27 +90,29 @@
}

protected WatchEvent translate(java.nio.file.WatchEvent<?> jdkEvent) {
WatchEvent.Kind kind;
if (jdkEvent.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
kind = WatchEvent.Kind.CREATED;
}
else if (jdkEvent.kind() == StandardWatchEventKinds.ENTRY_MODIFY) {
kind = WatchEvent.Kind.MODIFIED;
}
else if (jdkEvent.kind() == StandardWatchEventKinds.ENTRY_DELETE) {
kind = WatchEvent.Kind.DELETED;
}
else if (jdkEvent.kind() == StandardWatchEventKinds.OVERFLOW) {
kind = WatchEvent.Kind.OVERFLOW;
}
else {
throw new IllegalArgumentException("Unexpected watch event: " + jdkEvent);
}
var kind = translate(jdkEvent.kind());
var rootPath = path;
var relativePath = kind == WatchEvent.Kind.OVERFLOW ? Path.of("") : (@Nullable Path)jdkEvent.context();
var relativePath = kind == WatchEvent.Kind.OVERFLOW ? null : (@Nullable Path) jdkEvent.context();

var event = new WatchEvent(kind, rootPath, relativePath);
logger.trace("Translated: {} to {}", jdkEvent, event);
return event;
}

private WatchEvent.Kind translate(java.nio.file.WatchEvent.Kind<?> jdkKind) {
if (jdkKind == StandardWatchEventKinds.ENTRY_CREATE) {
return WatchEvent.Kind.CREATED;
}
if (jdkKind == StandardWatchEventKinds.ENTRY_MODIFY) {
return WatchEvent.Kind.MODIFIED;
}
if (jdkKind == StandardWatchEventKinds.ENTRY_DELETE) {
return WatchEvent.Kind.DELETED;
}
if (jdkKind == StandardWatchEventKinds.OVERFLOW) {
return WatchEvent.Kind.OVERFLOW;
}

throw new IllegalArgumentException("Unexpected watch kind: " + jdkKind);

Check warning on line 116 in src/main/java/engineering/swat/watch/impl/jdk/JDKBaseWatch.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/engineering/swat/watch/impl/jdk/JDKBaseWatch.java#L116

Added line #L116 was not covered by tests
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public JDKDirectoryWatch(Path directory, Executor exec, Consumer<WatchEvent> eve
this.nativeRecursive = nativeRecursive;
}

private void handleChanges(List<java.nio.file.WatchEvent<?>> events) {
private void handleJDKEvents(List<java.nio.file.WatchEvent<?>> events) {
exec.execute(() -> {
for (var ev : events) {
try {
Expand All @@ -85,6 +85,6 @@ public synchronized void close() throws IOException {
protected synchronized void start() throws IOException {
assert bundledJDKWatcher == null;
var key = new SubscriptionKey(path, nativeRecursive);
bundledJDKWatcher = BUNDLED_JDK_WATCHERS.subscribe(key, this::handleChanges);
bundledJDKWatcher = BUNDLED_JDK_WATCHERS.subscribe(key, this::handleJDKEvents);
}
}
34 changes: 14 additions & 20 deletions src/main/java/engineering/swat/watch/impl/jdk/JDKFileWatch.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.Nullable;

import engineering.swat.watch.WatchEvent;
Expand All @@ -45,17 +44,23 @@
*/
public class JDKFileWatch extends JDKBaseWatch {
private final Logger logger = LogManager.getLogger();
private final Path parent;
private final Path fileName;
private volatile @MonotonicNonNull JDKDirectoryWatch parentWatch;
private final JDKBaseWatch internal;

public JDKFileWatch(Path file, Executor exec, Consumer<WatchEvent> eventHandler) {
super(file, exec, eventHandler);

var message = "The root path is not a valid path for a file watch";
this.parent = requireNonNull(path.getParent(), message);
this.fileName = requireNonNull(path.getFileName(), message);
assert !parent.equals(path);
var parent = requireNonNull(file.getParent(), message);
var fileName = requireNonNull(file.getFileName(), message);
assert !parent.equals(file);

this.internal = new JDKDirectoryWatch(parent, exec, e -> {
if (fileName.equals(e.getRelativePath())) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if an overflow happens for the whole directory, we would still need to deal with that event and mark this file as overflow? or is that bugfix happening later?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think this will/should be "magically" covered by one of the next PRs. But, we'll need a test to check this. I added a reminder for this to #12.

eventHandler.accept(e);
}
});

logger.debug("File watch (for: {}) is in reality a directory watch (for: {}) with a filter (for: {})", file, parent, fileName);
}

private static Path requireNonNull(@Nullable Path p, String message) {
Expand All @@ -65,26 +70,15 @@ private static Path requireNonNull(@Nullable Path p, String message) {
return p;
}

private void filter(WatchEvent event) {
if (fileName.equals(event.getRelativePath())) {
eventHandler.accept(event);
}
}

// -- JDKBaseWatch --

@Override
public synchronized void close() throws IOException {
if (parentWatch != null) {
parentWatch.close();
}
internal.close();
}

@Override
protected synchronized void start() throws IOException {
assert parentWatch == null;
parentWatch = new JDKDirectoryWatch(parent, exec, this::filter);
parentWatch.open();
logger.debug("File watch (for: {}) is in reality a directory watch (for: {}) with a filter (for: {})", path, parent, fileName);
internal.open();
}
}