package cn.dreampie.server;
import cn.dreampie.common.util.scan.FileScaner;
import cn.dreampie.log.Logger;
import java.io.File;
import java.util.*;
/**
* Created by Dreampie on 16/9/7.
*/
public class ReloadRunnable extends Observable implements Runnable {
private static final Logger logger = Logger.getLogger(ReloadRunnable.class);
public static final int SCAN_INTERVAL_DEFAULT = 1000;
public static final int RELOAD_INTERVAL_DEFAULT = 1000;
private int scanInterval;
private int restartInterval;
private Set<File> files;
private Map<String, Long> fileModifieds = new HashMap<String, Long>();
private long lastErrorModified = 0;
private RestyServer server;
private FileScaner fileScaner;
private String[] includeFiles;
public ReloadRunnable(RestyServer server) {
this(SCAN_INTERVAL_DEFAULT, RELOAD_INTERVAL_DEFAULT, server);
}
public ReloadRunnable(int scanInterval, int restartInterval, RestyServer server) {
this.scanInterval = scanInterval;
this.restartInterval = restartInterval;
this.server = server;
this.includeFiles = new String[]{server.classPath, server.webXmlPath, server.rootPath + "pom.xml"};
this.fileScaner = FileScaner.of().isAbsolutePath(true);
this.files = fileScaner.include(includeFiles).scanToFile();
for (File file : files) {
fileModifieds.put(file.getAbsolutePath(), file.lastModified());
}
}
// 此方法一经调用,等待reloadInterval时间之后可以通知观察者,在本例中是通知监听线程
public void doNotify() {
logger.error("ReloadRunnable is dead.");
try {
if (!Thread.currentThread().isInterrupted()) {
Thread.sleep(restartInterval);
}
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
}
super.setChanged();
notifyObservers();
}
public void run() {
try {
//执行文件对比 并重启server
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
while (!Thread.currentThread().isInterrupted()) {
Thread.sleep(scanInterval);
this.files = this.fileScaner.include(includeFiles).scanToFile();
Iterator<File> fileIterator = files.iterator();
while (fileIterator.hasNext()) {
File file = fileIterator.next();
if (file.exists()) {
long fileLastModified = 0;
if (fileModifieds.containsKey(file.getAbsolutePath())) {
fileLastModified = fileModifieds.get(file.getAbsolutePath());
} else {
fileModifieds.put(file.getAbsolutePath(), file.lastModified());
}
//文件不存在 或者 当前文件更新时间变化
if (file.lastModified() > fileLastModified && lastErrorModified < file.lastModified()) {
lastErrorModified = new Date().getTime();
//启动的Main执行线程
if (file.getAbsolutePath().endsWith(server.mainFile)) {
logger.warn("Could not restart 'main' thread, you must rerun this application to enable this change.");
} else {
fileModifieds.put(file.getAbsolutePath(), file.lastModified());//reset last modify
logger.info("File '" + file.getAbsolutePath() + "' modified at '" + new Date(file.lastModified()) + "'.");
server.restartWebApp();
}
}
} else {
//删除不存在的文件
fileModifieds.remove(file.getAbsolutePath());
server.restartWebApp();
}
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
doNotify();
}
}
}