Skip to content

Commit e4a00aa

Browse files
committed
Add more DEBUG logs into the WatchServiceDirectoryScanner
With the fact of those logs provide more optimizations: * Don't register the same directory for watching: - use the `ConcurrentMap<Path, WatchKey> pathKeys` to track registrations - any modification within the directory causes the `ENTRY_MODIFY` for the directory as well. So, skip such an event exactly for the directory during `walkDirectory` * Add debug logs in case of `ENTRY_DELETE`
1 parent 9e2b954 commit e4a00aa

File tree

1 file changed

+38
-12
lines changed

1 file changed

+38
-12
lines changed

spring-integration-file/src/main/java/org/springframework/integration/file/FileReadingMessageSource.java

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
import java.util.List;
3636
import java.util.Queue;
3737
import java.util.Set;
38+
import java.util.concurrent.ConcurrentHashMap;
39+
import java.util.concurrent.ConcurrentMap;
3840
import java.util.concurrent.PriorityBlockingQueue;
3941

4042
import org.apache.commons.logging.Log;
@@ -423,6 +425,8 @@ public enum WatchEventType {
423425
@UsesJava7
424426
private class WatchServiceDirectoryScanner extends DefaultDirectoryScanner implements Lifecycle {
425427

428+
private final ConcurrentMap<Path, WatchKey> pathKeys = new ConcurrentHashMap<Path, WatchKey>();
429+
426430
private WatchService watcher;
427431

428432
private Collection<File> initialFiles;
@@ -444,7 +448,7 @@ public void start() {
444448
this.kinds[i] = FileReadingMessageSource.this.watchEvents[i].kind;
445449
}
446450

447-
final Set<File> initialFiles = walkDirectory(FileReadingMessageSource.this.directory.toPath());
451+
final Set<File> initialFiles = walkDirectory(FileReadingMessageSource.this.directory.toPath(), null);
448452
initialFiles.addAll(filesFromEvents());
449453
this.initialFiles = initialFiles;
450454
}
@@ -489,36 +493,53 @@ private Set<File> filesFromEvents() {
489493
Path item = (Path) event.context();
490494
File file = new File(parentDir, item.toFile().getName());
491495
if (logger.isDebugEnabled()) {
492-
logger.debug("Watch Event: " + event.kind() + ": " + file);
496+
logger.debug("Watch event [" + event.kind() + "] for file [" + file + "]");
493497
}
494498

495499
if (event.kind() == StandardWatchEventKinds.ENTRY_DELETE) {
496500
if (FileReadingMessageSource.this.filter instanceof ResettableFileListFilter) {
497501
((ResettableFileListFilter<File>) FileReadingMessageSource.this.filter).remove(file);
498502
}
499-
files.remove(file);
503+
boolean fileRemoved = files.remove(file);
504+
if (fileRemoved && logger.isDebugEnabled()) {
505+
logger.debug("The file [" + file +
506+
"] has been removed from the queue because of DELETE event.");
507+
}
500508
}
501509
else {
502510
if (file.exists()) {
503511
if (file.isDirectory()) {
504-
files.addAll(walkDirectory(file.toPath()));
512+
files.addAll(walkDirectory(file.toPath(), event.kind()));
505513
}
506514
else {
507515
files.remove(file);
508516
files.add(file);
509517
}
510518
}
519+
else {
520+
if (logger.isDebugEnabled()) {
521+
logger.debug("A file [" + file + "] for the event [" + event.kind() +
522+
"] doesn't exist. Ignored.");
523+
}
524+
}
511525
}
512526
}
513527
else if (event.kind() == StandardWatchEventKinds.OVERFLOW) {
514528
if (logger.isDebugEnabled()) {
515-
logger.debug("Watch Event: " + event.kind() + ": context: " + event.context());
529+
logger.debug("Watch event [" + StandardWatchEventKinds.OVERFLOW +
530+
"] with context [" + event.context() + "]");
531+
}
532+
533+
for (WatchKey watchKey : pathKeys.values()) {
534+
watchKey.cancel();
516535
}
536+
this.pathKeys.clear();
537+
517538
if (event.context() != null && event.context() instanceof Path) {
518-
files.addAll(walkDirectory((Path) event.context()));
539+
files.addAll(walkDirectory((Path) event.context(), event.kind()));
519540
}
520541
else {
521-
files.addAll(walkDirectory(FileReadingMessageSource.this.directory.toPath()));
542+
files.addAll(walkDirectory(FileReadingMessageSource.this.directory.toPath(), event.kind()));
522543
}
523544
}
524545
}
@@ -528,7 +549,7 @@ else if (event.kind() == StandardWatchEventKinds.OVERFLOW) {
528549
return files;
529550
}
530551

531-
private Set<File> walkDirectory(Path directory) {
552+
private Set<File> walkDirectory(Path directory, final WatchEvent.Kind<?> kind) {
532553
final Set<File> walkedFiles = new LinkedHashSet<File>();
533554
try {
534555
registerWatch(directory);
@@ -544,7 +565,9 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) th
544565
@Override
545566
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
546567
FileVisitResult fileVisitResult = super.visitFile(file, attrs);
547-
walkedFiles.add(file.toFile());
568+
if (!StandardWatchEventKinds.ENTRY_MODIFY.equals(kind)) {
569+
walkedFiles.add(file.toFile());
570+
}
548571
return fileVisitResult;
549572
}
550573

@@ -557,10 +580,13 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
557580
}
558581

559582
private void registerWatch(Path dir) throws IOException {
560-
if (logger.isDebugEnabled()) {
561-
logger.debug("registering: " + dir + " for file events");
583+
if (!this.pathKeys.containsKey(dir)) {
584+
if (logger.isDebugEnabled()) {
585+
logger.debug("registering: " + dir + " for file events");
586+
}
587+
WatchKey watchKey = dir.register(this.watcher, this.kinds);
588+
this.pathKeys.putIfAbsent(dir, watchKey);
562589
}
563-
dir.register(this.watcher, this.kinds);
564590
}
565591

566592
}

0 commit comments

Comments
 (0)