Stop file watcher as soon as a change is detected
The FileWatcher sometimes generates multiple events for a single change and if there is a slow shutdown hook the second one can come in before the context is closed, leaving it in a tricky state. This change attempts to stop the file watcher as soon as it detects a change (the stop() method is called in the listener, which normally happens in the same thread as the scan). Fixes gh-3097
This commit is contained in:
parent
983484f429
commit
b47af19920
|
|
@ -27,6 +27,7 @@ import org.springframework.boot.devtools.classpath.ClassPathChangedEvent;
|
|||
import org.springframework.boot.devtools.classpath.ClassPathFileSystemWatcher;
|
||||
import org.springframework.boot.devtools.classpath.ClassPathRestartStrategy;
|
||||
import org.springframework.boot.devtools.classpath.PatternClassPathRestartStrategy;
|
||||
import org.springframework.boot.devtools.filewatch.FileSystemWatcher;
|
||||
import org.springframework.boot.devtools.livereload.LiveReloadServer;
|
||||
import org.springframework.boot.devtools.restart.ConditionalOnInitializedRestarter;
|
||||
import org.springframework.boot.devtools.restart.RestartScope;
|
||||
|
|
@ -103,11 +104,14 @@ public class LocalDevToolsAutoConfiguration {
|
|||
@Autowired
|
||||
private DevToolsProperties properties;
|
||||
|
||||
private final FileSystemWatcher fileSystemWatcher = new FileSystemWatcher();
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ClassPathFileSystemWatcher classPathFileSystemWatcher() {
|
||||
URL[] urls = Restarter.getInstance().getInitialUrls();
|
||||
return new ClassPathFileSystemWatcher(classPathRestartStrategy(), urls);
|
||||
return new ClassPathFileSystemWatcher(this.fileSystemWatcher,
|
||||
classPathRestartStrategy(), urls);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
|
@ -120,6 +124,7 @@ public class LocalDevToolsAutoConfiguration {
|
|||
@EventListener
|
||||
public void onClassPathChanged(ClassPathChangedEvent event) {
|
||||
if (event.isRestartRequired()) {
|
||||
this.fileSystemWatcher.stop();
|
||||
Restarter.getInstance().restart();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,11 +72,11 @@ public class ClassPathFileSystemWatcher implements InitializingBean, DisposableB
|
|||
* @param restartStrategy the classpath restart strategy
|
||||
* @param urls the URLs to watch
|
||||
*/
|
||||
protected ClassPathFileSystemWatcher(FileSystemWatcher fileSystemWatcher,
|
||||
public ClassPathFileSystemWatcher(FileSystemWatcher fileSystemWatcher,
|
||||
ClassPathRestartStrategy restartStrategy, URL[] urls) {
|
||||
Assert.notNull(fileSystemWatcher, "FileSystemWatcher must not be null");
|
||||
Assert.notNull(urls, "Urls must not be null");
|
||||
this.fileSystemWatcher = new FileSystemWatcher();
|
||||
this.fileSystemWatcher = fileSystemWatcher;
|
||||
this.restartStrategy = restartStrategy;
|
||||
addUrls(urls);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -199,13 +199,16 @@ public class FileSystemWatcher {
|
|||
Thread thread = this.watchThread;
|
||||
if (thread != null) {
|
||||
this.remainingScans.set(remainingScans);
|
||||
try {
|
||||
thread.join();
|
||||
}
|
||||
catch (InterruptedException ex) {
|
||||
Thread.currentThread().interrupt();
|
||||
if (Thread.currentThread() != thread) {
|
||||
try {
|
||||
thread.join();
|
||||
}
|
||||
catch (InterruptedException ex) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
this.watchThread = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue