Allow custom restart pollInterval and quietPeriod
Allow the pollInterval and the quietPeriod of the filewatcher to be configured. Fixes gh-3139
This commit is contained in:
@@ -29,6 +29,10 @@ public class DevToolsProperties {
|
||||
|
||||
private static final String DEFAULT_RESTART_EXCLUDES = "META-INF/resources/**,resource/**,static/**,public/**,templates/**";
|
||||
|
||||
private static final long DEFAULT_RESTART_POLL_INTERVAL = 1000;
|
||||
|
||||
private static final long DEFAULT_RESTART_QUIET_PERIOD = 400;
|
||||
|
||||
private Restart restart = new Restart();
|
||||
|
||||
private Livereload livereload = new Livereload();
|
||||
@@ -62,6 +66,17 @@ public class DevToolsProperties {
|
||||
*/
|
||||
private String exclude = DEFAULT_RESTART_EXCLUDES;
|
||||
|
||||
/**
|
||||
* Amount of time (in milliseconds) to wait between polling for classpath changes.
|
||||
*/
|
||||
private long pollInterval = DEFAULT_RESTART_POLL_INTERVAL;
|
||||
|
||||
/**
|
||||
* Amount of quiet time (in milliseconds) requited without any classpath changes
|
||||
* before a restart is triggered.
|
||||
*/
|
||||
private long quietPeriod = DEFAULT_RESTART_QUIET_PERIOD;
|
||||
|
||||
/**
|
||||
* The name of specific that that when changed will will trigger the restart. If
|
||||
* not specified any classpath file change will trigger the restart.
|
||||
@@ -84,6 +99,22 @@ public class DevToolsProperties {
|
||||
this.exclude = exclude;
|
||||
}
|
||||
|
||||
public long getPollInterval() {
|
||||
return this.pollInterval;
|
||||
}
|
||||
|
||||
public void setPollInterval(long pollInterval) {
|
||||
this.pollInterval = pollInterval;
|
||||
}
|
||||
|
||||
public long getQuietPeriod() {
|
||||
return this.quietPeriod;
|
||||
}
|
||||
|
||||
public void setQuietPeriod(long quietPeriod) {
|
||||
this.quietPeriod = quietPeriod;
|
||||
}
|
||||
|
||||
public String getTriggerFile() {
|
||||
return this.triggerFile;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.devtools.autoconfigure.DevToolsProperties.Restart;
|
||||
import org.springframework.boot.devtools.classpath.ClassPathChangedEvent;
|
||||
import org.springframework.boot.devtools.classpath.ClassPathFileSystemWatcher;
|
||||
import org.springframework.boot.devtools.classpath.ClassPathRestartStrategy;
|
||||
@@ -130,8 +131,11 @@ public class LocalDevToolsAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public FileSystemWatcher getFileSystemWatcher() {
|
||||
FileSystemWatcher watcher = new FileSystemWatcher();
|
||||
String triggerFile = this.properties.getRestart().getTriggerFile();
|
||||
Restart restartProperties = this.properties.getRestart();
|
||||
FileSystemWatcher watcher = new FileSystemWatcher(true,
|
||||
restartProperties.getPollInterval(),
|
||||
restartProperties.getQuietPeriod());
|
||||
String triggerFile = restartProperties.getTriggerFile();
|
||||
if (StringUtils.hasLength(triggerFile)) {
|
||||
watcher.setTriggerFilter(new TriggerFileFilter(triggerFile));
|
||||
}
|
||||
|
||||
@@ -40,17 +40,17 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class FileSystemWatcher {
|
||||
|
||||
private static final long DEFAULT_IDLE_TIME = 400;
|
||||
private static final long DEFAULT_POLL_INTERVAL = 1000;
|
||||
|
||||
private static final long DEFAULT_QUIET_TIME = 200;
|
||||
private static final long DEFAULT_QUIET_PERIOD = 400;
|
||||
|
||||
private List<FileChangeListener> listeners = new ArrayList<FileChangeListener>();
|
||||
|
||||
private final boolean daemon;
|
||||
|
||||
private final long idleTime;
|
||||
private final long pollInterval;
|
||||
|
||||
private final long quietTime;
|
||||
private final long quietPeriod;
|
||||
|
||||
private Thread watchThread;
|
||||
|
||||
@@ -64,20 +64,24 @@ public class FileSystemWatcher {
|
||||
* Create a new {@link FileSystemWatcher} instance.
|
||||
*/
|
||||
public FileSystemWatcher() {
|
||||
this(true, DEFAULT_IDLE_TIME, DEFAULT_QUIET_TIME);
|
||||
this(true, DEFAULT_POLL_INTERVAL, DEFAULT_QUIET_PERIOD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link FileSystemWatcher} instance.
|
||||
* @param daemon if a daemon thread used to monitor changes
|
||||
* @param idleTime the amount of time to wait between checking for changes
|
||||
* @param quietTime the amount of time required after a change has been detected to
|
||||
* @param pollInterval the amount of time to wait between checking for changes
|
||||
* @param quietPeriod the amount of time required after a change has been detected to
|
||||
* ensure that updates have completed
|
||||
*/
|
||||
public FileSystemWatcher(boolean daemon, long idleTime, long quietTime) {
|
||||
public FileSystemWatcher(boolean daemon, long pollInterval, long quietPeriod) {
|
||||
Assert.isTrue(pollInterval > 0, "PollInterval must be positive");
|
||||
Assert.isTrue(quietPeriod > 0, "QuietPeriod must be positive");
|
||||
Assert.isTrue(pollInterval > quietPeriod,
|
||||
"PollInterval must be greater than QuietPeriod");
|
||||
this.daemon = daemon;
|
||||
this.idleTime = idleTime;
|
||||
this.quietTime = quietTime;
|
||||
this.pollInterval = pollInterval;
|
||||
this.quietPeriod = quietPeriod;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,10 +135,10 @@ public class FileSystemWatcher {
|
||||
FileSystemWatcher.this.remainingScans.decrementAndGet();
|
||||
}
|
||||
scan();
|
||||
remainingScans = FileSystemWatcher.this.remainingScans.get();
|
||||
}
|
||||
catch (InterruptedException ex) {
|
||||
}
|
||||
remainingScans = FileSystemWatcher.this.remainingScans.get();
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -152,13 +156,13 @@ public class FileSystemWatcher {
|
||||
}
|
||||
|
||||
private void scan() throws InterruptedException {
|
||||
Thread.sleep(this.idleTime - this.quietTime);
|
||||
Thread.sleep(this.pollInterval - this.quietPeriod);
|
||||
Map<File, FolderSnapshot> previous;
|
||||
Map<File, FolderSnapshot> current = this.folders;
|
||||
do {
|
||||
previous = current;
|
||||
current = getCurrentSnapshots();
|
||||
Thread.sleep(this.quietTime);
|
||||
Thread.sleep(this.quietPeriod);
|
||||
}
|
||||
while (isDifferent(previous, current));
|
||||
if (isDifferent(this.folders, current)) {
|
||||
@@ -228,6 +232,7 @@ public class FileSystemWatcher {
|
||||
Thread thread = this.watchThread;
|
||||
if (thread != null) {
|
||||
this.remainingScans.set(remainingScans);
|
||||
thread.interrupt();
|
||||
if (Thread.currentThread() != thread) {
|
||||
try {
|
||||
thread.join();
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.devtools.autoconfigure.DevToolsProperties;
|
||||
import org.springframework.boot.devtools.autoconfigure.DevToolsProperties.Restart;
|
||||
import org.springframework.boot.devtools.autoconfigure.OptionalLiveReloadServer;
|
||||
import org.springframework.boot.devtools.autoconfigure.RemoteDevToolsProperties;
|
||||
import org.springframework.boot.devtools.autoconfigure.TriggerFileFilter;
|
||||
@@ -187,8 +188,11 @@ public class RemoteClientConfiguration {
|
||||
|
||||
@Bean
|
||||
public FileSystemWatcher getFileSystemWather() {
|
||||
FileSystemWatcher watcher = new FileSystemWatcher();
|
||||
String triggerFile = this.properties.getRestart().getTriggerFile();
|
||||
Restart restartProperties = this.properties.getRestart();
|
||||
FileSystemWatcher watcher = new FileSystemWatcher(true,
|
||||
restartProperties.getPollInterval(),
|
||||
restartProperties.getQuietPeriod());
|
||||
String triggerFile = restartProperties.getTriggerFile();
|
||||
if (StringUtils.hasLength(triggerFile)) {
|
||||
watcher.setTriggerFilter(new TriggerFileFilter(triggerFile));
|
||||
}
|
||||
|
||||
@@ -64,6 +64,27 @@ public class FileSystemWatcherTests {
|
||||
setupWatcher(20, 10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pollIntervalMustBePositive() throws Exception {
|
||||
this.thrown.expect(IllegalArgumentException.class);
|
||||
this.thrown.expectMessage("PollInterval must be positive");
|
||||
new FileSystemWatcher(true, 0, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void quietPeriodMustBePositive() throws Exception {
|
||||
this.thrown.expect(IllegalArgumentException.class);
|
||||
this.thrown.expectMessage("QuietPeriod must be positive");
|
||||
new FileSystemWatcher(true, 1, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pollIntervalMustBeGreaterThanQuietPeriod() throws Exception {
|
||||
this.thrown.expect(IllegalArgumentException.class);
|
||||
this.thrown.expectMessage("PollInterval must be greater than QuietPeriod");
|
||||
new FileSystemWatcher(true, 1, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listenerMustNotBeNull() throws Exception {
|
||||
this.thrown.expect(IllegalArgumentException.class);
|
||||
@@ -117,7 +138,7 @@ public class FileSystemWatcherTests {
|
||||
@Test
|
||||
public void waitsForIdleTime() throws Exception {
|
||||
this.changes.clear();
|
||||
setupWatcher(100, 0);
|
||||
setupWatcher(100, 1);
|
||||
File folder = startWithNewFolder();
|
||||
touch(new File(folder, "test1.txt"));
|
||||
Thread.sleep(200);
|
||||
|
||||
Reference in New Issue
Block a user