mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 16:53:04 +08:00
fix(DirectoryWatchSupport): isolate handler failures
This commit is contained in:
@@ -157,7 +157,11 @@ public class DirectoryWatchSupport implements Closeable {
|
|||||||
if (handler == null) {
|
if (handler == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
handler.handle(thisDir, resolvedContext);
|
try {
|
||||||
|
handler.handle(thisDir, resolvedContext);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("监听事件处理失败: dir={}, kind={}, context={}", thisDir, kind.name(), resolvedContext, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
log.info("监听线程被中断,准备退出...");
|
log.info("监听线程被中断,准备退出...");
|
||||||
|
|||||||
@@ -11,8 +11,11 @@ import java.nio.file.Path;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.function.BooleanSupplier;
|
import java.util.function.BooleanSupplier;
|
||||||
|
|
||||||
class DirectoryWatchSupportTest {
|
class DirectoryWatchSupportTest {
|
||||||
@@ -115,6 +118,41 @@ class DirectoryWatchSupportTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHandlerExceptionDoesNotStopWatching(@TempDir Path tempDir) throws Exception {
|
||||||
|
AtomicBoolean shouldThrow = new AtomicBoolean(true);
|
||||||
|
CountDownLatch goodEventLatch = new CountDownLatch(1);
|
||||||
|
|
||||||
|
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
||||||
|
DirectoryWatchSupport watchSupport = new DirectoryWatchSupport(
|
||||||
|
new DirectoryWatchSupport.Context(tempDir),
|
||||||
|
executor,
|
||||||
|
0,
|
||||||
|
null
|
||||||
|
)) {
|
||||||
|
List<String> events = new CopyOnWriteArrayList<>();
|
||||||
|
watchSupport.onCreate((thisDir, context) -> {
|
||||||
|
if (context == null || Files.isDirectory(context)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String relative = tempDir.relativize(context).toString().replace('\\', '/');
|
||||||
|
if (shouldThrow.getAndSet(false)) {
|
||||||
|
throw new IllegalStateException("boom");
|
||||||
|
}
|
||||||
|
events.add(relative);
|
||||||
|
goodEventLatch.countDown();
|
||||||
|
});
|
||||||
|
|
||||||
|
watchSupport.start();
|
||||||
|
|
||||||
|
Files.writeString(tempDir.resolve("first.txt"), "first");
|
||||||
|
Files.writeString(tempDir.resolve("second.txt"), "second");
|
||||||
|
|
||||||
|
Assertions.assertTrue(goodEventLatch.await(2, TimeUnit.SECONDS));
|
||||||
|
Assertions.assertEquals(List.of("second.txt"), events);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private WatchHarness createWatchSupport(Path root, ExecutorService executor, int watchDepth) throws IOException {
|
private WatchHarness createWatchSupport(Path root, ExecutorService executor, int watchDepth) throws IOException {
|
||||||
DirectoryWatchSupport watchSupport = new DirectoryWatchSupport(new DirectoryWatchSupport.Context(root), executor, watchDepth, null);
|
DirectoryWatchSupport watchSupport = new DirectoryWatchSupport(new DirectoryWatchSupport.Context(root), executor, watchDepth, null);
|
||||||
List<String> events = new CopyOnWriteArrayList<>();
|
List<String> events = new CopyOnWriteArrayList<>();
|
||||||
|
|||||||
Reference in New Issue
Block a user