All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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