
com.jianggujin.modulelink.util.JAbstractModuleRefreshScheduler Maven / Gradle / Ivy
/**
* Copyright 2018-2018 jianggujin (www.jianggujin.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jianggujin.modulelink.util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.jianggujin.modulelink.JModule;
import com.jianggujin.modulelink.JModuleConfig;
import com.jianggujin.modulelink.JModuleManager;
import com.jianggujin.modulelink.impl.JAbstractModuleManager;
import com.jianggujin.modulelink.util.JLogFactory.JLog;
/**
* 带有刷新计划的抽象模块管理器
*
* @author jianggujin
*
*/
public abstract class JAbstractModuleRefreshScheduler implements Runnable {
private final JLog logger = JLogFactory.getLog(JAbstractModuleRefreshScheduler.class);
/**
* 默认延迟执行,单位秒
*/
private static final int DEFAULT_INITIAL_DELAY = 5;
/**
* 模块刷新默认间隔,单位秒
*/
private static final int DEFAULT_REFRESH_DELAY = 60;
/** 初始化的延迟时间 */
private int initialDelay = DEFAULT_INITIAL_DELAY;
/** 刷新间隔时间 */
private int refreshDelay = DEFAULT_REFRESH_DELAY;
private ScheduledExecutorService scheduledExecutor;
private boolean enableScheduled = true;
private final JModuleManager moduleManager;
public JAbstractModuleRefreshScheduler(JAbstractModuleManager moduleManager) {
JAssert.checkNotNull(moduleManager, "moduleManager must not be null.");
this.moduleManager = moduleManager;
}
/**
* 初始化ScheduledExecutor,启动定时任务
*
*/
public void afterPropertiesSet() throws Exception {
// 先刷新一次
refreshModuleConfigs();
if (enableScheduled) {
scheduledExecutor = new ScheduledThreadPoolExecutor(1, new JThreadFactory("JModuleLink_refresh-schedule-"));
scheduledExecutor.scheduleWithFixedDelay(this, initialDelay, refreshDelay, TimeUnit.SECONDS);
if (logger.isInfoEnabled()) {
logger.info("JAbstractModuleRefreshScheduler start");
}
}
}
/**
* 关闭ScheduledExecutor
*/
public void destroy() throws Exception {
if (scheduledExecutor != null) {
scheduledExecutor.shutdownNow();
}
}
/**
* ScheduledExecutor 定时运行的方法
*
* @see Runnable#run()
*/
@Override
public void run() {
try {
if (logger.isInfoEnabled()) {
logger.info("Start Module refresh");
}
refreshModuleConfigs();
if (logger.isInfoEnabled()) {
logger.info("Stop Module refresh");
}
} catch (Throwable e) {
logger.error("Failed to refresh Module", e);
}
}
/**
* 刷新
*/
protected void refreshModuleConfigs() {
JMultiValueMap queryInfos = new JDefaultMultiValueMap();
// 查询到的模块配置信息
List queryConfigs = queryModuleConfigs(queryInfos);
JMultiValueMap runtimeInfos = new JDefaultMultiValueMap();
// 运行中的模块配置信息
List runtimeConfigs = runtimeModuleConfigs(runtimeInfos);
// 处理新增的模块
loadModule(queryConfigs, runtimeInfos);
// 处理卸载的配置
unLoadModule(runtimeConfigs, queryInfos);
}
/**
* 加载新模块
*
* @param queryConfigs
* @param runtimeInfos
*/
protected void loadModule(List queryConfigs, JMultiValueMap runtimeInfos) {
for (JModuleConfig moduleConfig : queryConfigs) {
String name = moduleConfig.getName();
if (runtimeInfos.containsKey(name)) {
List versions = runtimeInfos.get(name);
// 不存在,则需要添加
if (!versions.contains(moduleConfig.getVersion())) {
this.loadModule(moduleConfig);
}
} else {
this.loadModule(moduleConfig);
}
}
}
protected void loadModule(JModuleConfig moduleConfig) {
try {
this.moduleManager.load(moduleConfig);
} catch (Throwable e) {
logger.error("load module error.", e);
}
}
/**
* 移除已加载模块
*
* @param runtimeConfigs
* @param queryInfos
*/
protected void unLoadModule(List runtimeConfigs, JMultiValueMap queryInfos) {
for (JModuleConfig moduleConfig : runtimeConfigs) {
String name = moduleConfig.getName();
String version = moduleConfig.getVersion();
if (queryInfos.containsKey(name)) {
List products = queryInfos.get(name);
// 不存在,则需要卸载
if (!products.contains(version)) {
this.unLoadModule(name, version);
}
} else {
this.unLoadModule(name, version);
}
}
}
protected void unLoadModule(String name, String version) {
try {
this.moduleManager.unload(name, version);
} catch (Throwable e) {
logger.error("load module error.", e);
}
}
@SuppressWarnings("unchecked")
protected List queryModuleConfigs(JMultiValueMap moduleNameVersions) {
List moduleConfigs = queryModuleConfigs();
if (moduleConfigs == null)
return Collections.EMPTY_LIST;
for (JModuleConfig moduleConfig : moduleConfigs) {
moduleNameVersions.add(moduleConfig.getName(), moduleConfig.getVersion());
}
return moduleConfigs;
}
protected List runtimeModuleConfigs(JMultiValueMap moduleNameVersions) {
List modules = this.moduleManager.getModules();
List moduleConfigs = new ArrayList((int) (modules.size() / 0.75f + 1));
for (JModule module : modules) {
JModuleConfig moduleConfig = module.getModuleConfig();
moduleConfigs.add(moduleConfig);
moduleNameVersions.add(moduleConfig.getName(), moduleConfig.getVersion());
}
return moduleConfigs;
}
public void setInitialDelay(int initialDelay) {
this.initialDelay = initialDelay;
}
public void setRefreshDelay(int refreshDelay) {
this.refreshDelay = refreshDelay;
}
public boolean isEnableScheduled() {
return enableScheduled;
}
public void setEnableScheduled(boolean enableScheduled) {
this.enableScheduled = enableScheduled;
}
/**
* 获取模块配置信息
*
* @return
*/
public abstract List queryModuleConfigs();
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy