Skip to content

Commit f057b4b

Browse files
committed
Few fixes from review
1 parent c64ea4f commit f057b4b

File tree

3 files changed

+44
-62
lines changed

3 files changed

+44
-62
lines changed

worldedit-core/src/main/java/com/sk89q/worldedit/internal/schematic/SchematicsManager.java

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,12 @@ public SchematicsManager(WorldEdit worldEdit) {
5454
this.worldEdit = worldEdit;
5555
}
5656

57-
private void createFallbackBackend() {
58-
LOGGER.warn("Failed to initialize file-monitoring based schematics backend. Falling back to polling.");
59-
backend = PollingSchematicsBackend.create(schematicsDir);
60-
}
61-
6257
private void setupBackend() {
6358
try {
64-
var fileWatcherBackend = FileWatcherSchematicsBackend.create(schematicsDir);
65-
if (fileWatcherBackend.isPresent()) {
66-
backend = fileWatcherBackend.get();
67-
} else {
68-
createFallbackBackend();
69-
}
59+
backend = FileWatcherSchematicsBackend.create(schematicsDir);
7060
} catch (IOException e) {
71-
createFallbackBackend();
61+
LOGGER.warn("Failed to initialize file-monitoring based schematics backend. Falling back to polling.", e);
62+
backend = PollingSchematicsBackend.create(schematicsDir);
7263
}
7364
}
7465

@@ -78,13 +69,13 @@ private void setupBackend() {
7869
*/
7970
public void init() {
8071
try {
81-
schematicsDir = worldEdit.getWorkingDirectoryPath(worldEdit.getConfiguration().saveDir);
82-
Files.createDirectories(schematicsDir);
83-
schematicsDir = schematicsDir.toRealPath();
72+
Path schematicsDirByConfig = worldEdit.getWorkingDirectoryPath(worldEdit.getConfiguration().saveDir);
73+
Files.createDirectories(schematicsDirByConfig);
74+
schematicsDir = schematicsDirByConfig.toRealPath();
8475
setupBackend();
8576
} catch (IOException e) {
8677
LOGGER.warn("Failed to create schematics directory", e);
87-
backend = new DummySchematicsBackend(); //fallback to dummy backend
78+
backend = new DummySchematicsBackend();
8879
}
8980
backend.init();
9081
}

worldedit-core/src/main/java/com/sk89q/worldedit/internal/schematic/backends/FileWatcherSchematicsBackend.java

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,22 @@
1919

2020
package com.sk89q.worldedit.internal.schematic.backends;
2121

22+
import com.google.common.collect.Sets;
2223
import com.sk89q.worldedit.internal.util.LogManagerCompat;
2324
import com.sk89q.worldedit.internal.util.RecursiveDirectoryWatcher;
2425
import org.apache.logging.log4j.Logger;
2526

2627
import java.io.IOException;
2728
import java.nio.file.Path;
28-
import java.util.HashSet;
29-
import java.util.Optional;
3029
import java.util.Set;
31-
import java.util.concurrent.locks.ReentrantReadWriteLock;
3230

3331
/**
3432
* A backend that efficiently scans for file changes using {@link RecursiveDirectoryWatcher}.
3533
*/
3634
public class FileWatcherSchematicsBackend implements SchematicsBackend {
3735
private static final Logger LOGGER = LogManagerCompat.getLogger();
3836

39-
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
40-
private final Set<Path> schematics = new HashSet<>();
37+
private final Set<Path> schematics = Sets.newConcurrentHashSet();
4138
private final RecursiveDirectoryWatcher directoryWatcher;
4239

4340
private FileWatcherSchematicsBackend(RecursiveDirectoryWatcher directoryWatcher) {
@@ -50,24 +47,19 @@ private FileWatcherSchematicsBackend(RecursiveDirectoryWatcher directoryWatcher)
5047
* @return A new FileWatcherSchematicsBackend instance.
5148
* @throws IOException When creation of the filesystem watcher fails.
5249
*/
53-
public static Optional<FileWatcherSchematicsBackend> create(Path schematicsFolder) throws IOException {
54-
return RecursiveDirectoryWatcher.create(schematicsFolder).map(FileWatcherSchematicsBackend::new);
50+
public static FileWatcherSchematicsBackend create(Path schematicsFolder) throws IOException {
51+
return new FileWatcherSchematicsBackend(RecursiveDirectoryWatcher.create(schematicsFolder));
5552
}
5653

5754
@Override
5855
public void init() {
5956
directoryWatcher.start(event -> {
60-
lock.writeLock().lock();
61-
try {
62-
if (event instanceof RecursiveDirectoryWatcher.FileCreatedEvent) {
63-
schematics.add(event.path());
64-
LOGGER.debug("New Schematic found: " + event.path());
65-
} else if (event instanceof RecursiveDirectoryWatcher.FileDeletedEvent) {
66-
schematics.remove(event.path());
67-
LOGGER.debug("Schematic deleted: " + event.path());
68-
}
69-
} finally {
70-
lock.writeLock().unlock();
57+
if (event instanceof RecursiveDirectoryWatcher.FileCreatedEvent) {
58+
schematics.add(event.path());
59+
LOGGER.debug("New Schematic found: " + event.path());
60+
} else if (event instanceof RecursiveDirectoryWatcher.FileDeletedEvent) {
61+
schematics.remove(event.path());
62+
LOGGER.debug("Schematic deleted: " + event.path());
7163
}
7264
});
7365
}
@@ -79,12 +71,7 @@ public void uninit() {
7971

8072
@Override
8173
public Set<Path> getPaths() {
82-
lock.readLock().lock();
83-
try {
84-
return Set.copyOf(schematics);
85-
} finally {
86-
lock.readLock().unlock();
87-
}
74+
return Set.copyOf(schematics);
8875
}
8976

9077
@Override

worldedit-core/src/main/java/com/sk89q/worldedit/internal/util/RecursiveDirectoryWatcher.java

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,7 @@
2727

2828
import java.io.Closeable;
2929
import java.io.IOException;
30-
import java.nio.file.ClosedWatchServiceException;
31-
import java.nio.file.Files;
32-
import java.nio.file.Path;
33-
import java.nio.file.StandardWatchEventKinds;
34-
import java.nio.file.WatchEvent;
35-
import java.nio.file.WatchKey;
36-
import java.nio.file.WatchService;
37-
import java.util.Optional;
30+
import java.nio.file.*;
3831
import java.util.function.Consumer;
3932

4033
/**
@@ -98,13 +91,14 @@ private RecursiveDirectoryWatcher(Path root, WatchService watchService) {
9891
* @return a new instance that will monitor the given root folder
9992
* @throws IOException If creating the watcher failed, e.g. due to root not existing.
10093
*/
101-
public static Optional<RecursiveDirectoryWatcher> create(Path root) throws IOException {
94+
public static RecursiveDirectoryWatcher create(Path root) throws IOException {
95+
WatchService watchService;
10296
try {
103-
WatchService watchService = root.getFileSystem().newWatchService();
104-
return Optional.of(new RecursiveDirectoryWatcher(root, watchService));
105-
} catch (UnsupportedOperationException ignored) {
106-
return Optional.empty();
97+
watchService = root.getFileSystem().newWatchService();
98+
} catch (UnsupportedOperationException e) {
99+
throw new IllegalArgumentException("Root must support file watching", e);
107100
}
101+
return new RecursiveDirectoryWatcher(root, watchService);
108102
}
109103

110104
private void registerFolderWatcher(Path root) throws IOException {
@@ -116,12 +110,14 @@ private void registerFolderWatcher(Path root) throws IOException {
116110
private void triggerInitialEvents(Path root) throws IOException, FilenameException {
117111
Path schematicRoot = WorldEdit.getInstance().getSchematicsManager().getRoot();
118112
eventConsumer.accept(new DirectoryCreatedEvent(root));
119-
for (Path path : Files.newDirectoryStream(root)) {
120-
path = WorldEdit.getInstance().getSafeOpenFile(null, schematicRoot.toFile(), schematicRoot.relativize(path).toString(), null).toPath();
121-
if (Files.isDirectory(path)) {
122-
triggerInitialEvents(path);
123-
} else {
124-
eventConsumer.accept(new FileCreatedEvent(path));
113+
try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(root)) {
114+
for (Path path : directoryStream) {
115+
path = WorldEdit.getInstance().getSafeOpenFile(null, schematicRoot.toFile(), schematicRoot.relativize(path).toString(), null).toPath();
116+
if (Files.isDirectory(path)) {
117+
triggerInitialEvents(path);
118+
} else {
119+
eventConsumer.accept(new FileCreatedEvent(path));
120+
}
125121
}
126122
}
127123
}
@@ -136,6 +132,12 @@ public void start(Consumer<DirEntryChangeEvent> eventConsumer) {
136132
Path schematicRoot = WorldEdit.getInstance().getSchematicsManager().getRoot();
137133

138134
this.eventConsumer = eventConsumer;
135+
136+
if (watchThread != null) {
137+
// We have an existing thread, interrupt it first to trigger a clean shutdown
138+
watchThread.interrupt();
139+
}
140+
139141
watchThread = new Thread(() -> {
140142
LOGGER.debug("RecursiveDirectoryWatcher::EventConsumer started");
141143

@@ -148,10 +150,12 @@ public void start(Consumer<DirEntryChangeEvent> eventConsumer) {
148150

149151
try {
150152
WatchKey watchKey;
151-
while (true) {
153+
while (!Thread.interrupted()) {
152154
try {
153155
watchKey = watchService.take();
154-
} catch (InterruptedException e) { break; }
156+
} catch (InterruptedException e) {
157+
break;
158+
}
155159

156160
for (WatchEvent<?> event : watchKey.pollEvents()) {
157161
WatchEvent.Kind<?> kind = event.kind();
@@ -205,7 +209,7 @@ public void start(Consumer<DirEntryChangeEvent> eventConsumer) {
205209
}
206210
LOGGER.debug("RecursiveDirectoryWatcher::EventConsumer exited");
207211
});
208-
watchThread.setName("RecursiveDirectoryWatcher");
212+
watchThread.setName("WorldEdit-RecursiveDirectoryWatcher");
209213
watchThread.start();
210214
}
211215

0 commit comments

Comments
 (0)