package com.dianping.pigeon.remoting.provider.config; import com.dianping.pigeon.config.ConfigChangeListener; import com.dianping.pigeon.config.ConfigManagerLoader; import com.dianping.pigeon.log.Logger; import com.dianping.pigeon.log.LoggerLoader; import com.dianping.pigeon.remoting.provider.process.threadpool.DynamicThreadPoolFactory; import com.dianping.pigeon.threadpool.DynamicThreadPool; import com.google.common.collect.Maps; import org.apache.commons.lang.StringUtils; import java.util.Map; import java.util.concurrent.ConcurrentMap; /** * Created by chenchongze on 16/11/28. */ public class PoolConfigFactory { private static final Logger logger = LoggerLoader.getLogger(PoolConfigFactory.class); // poolName --> poolConfig private static final ConcurrentMap<String, PoolConfig> poolConfigs = Maps.newConcurrentMap(); // poolName --> (core/max/queue)key private static final ConcurrentMap<String, String> coreSizeKeys = Maps.newConcurrentMap(); private static final ConcurrentMap<String, String> maxSizeKeys = Maps.newConcurrentMap(); private static final ConcurrentMap<String, String> queueSizeKeys = Maps.newConcurrentMap(); static { ConfigManagerLoader.getConfigManager().registerConfigChangeListener(new InnerConfigChangeListener()); } public static PoolConfig createPoolConfig(String poolName, int coreSize, int maxSize, int queueSize) { PoolConfig poolConfig = poolConfigs.get(poolName); if (poolConfig == null) { poolConfig = new PoolConfig(); poolConfig.setPoolName(poolName); poolConfig.setCorePoolSize(coreSize); poolConfig.setMaxPoolSize(maxSize); poolConfig.setWorkQueueSize(queueSize); poolConfigs.put(poolName, poolConfig); } return poolConfig; } public static boolean validate(PoolConfig poolConfig) { if (StringUtils.isNotBlank(poolConfig.getPoolName()) && poolConfig.getCorePoolSize() >= 0 && poolConfig.getMaxPoolSize() > 0 && poolConfig.getMaxPoolSize() >= poolConfig.getCorePoolSize() && poolConfig.getWorkQueueSize() > 0) { return true; } return false; } public static ConcurrentMap<String, String> getCoreSizeKeys() { return coreSizeKeys; } public static ConcurrentMap<String, String> getMaxSizeKeys() { return maxSizeKeys; } public static ConcurrentMap<String, String> getQueueSizeKeys() { return queueSizeKeys; } private static class InnerConfigChangeListener implements ConfigChangeListener { @Override public void onKeyUpdated(String key, String value) { for (Map.Entry<String, String> entry : coreSizeKeys.entrySet()) { String poolName = entry.getKey(); String coreSizeKey = entry.getValue(); if (key.endsWith(coreSizeKey)) { try { Integer coreSize = Integer.parseInt(value); PoolConfig poolConfig = poolConfigs.get(poolName); if (poolConfig != null) { if (coreSize < 0 || coreSize > poolConfig.getMaxPoolSize()) { throw new IllegalArgumentException("core size is illegal, please check: " + coreSize); } poolConfig.setCorePoolSize(coreSize); DynamicThreadPoolFactory.refreshThreadPool(poolConfig); } logger.info("changed core size of pool: " + poolName + ", key: " + key + ", value: " + value); } catch (RuntimeException e) { logger.error("error while changing pool, key:" + key + ", value:" + value, e); } } } for (Map.Entry<String, String> entry : maxSizeKeys.entrySet()) { String poolName = entry.getKey(); String maxSizeKey = entry.getValue(); if (key.endsWith(maxSizeKey)) { try { Integer maxSize = Integer.parseInt(value); PoolConfig poolConfig = poolConfigs.get(poolName); if (poolConfig != null) { if (maxSize < poolConfig.getCorePoolSize() || maxSize <= 0) { throw new IllegalArgumentException("max size is illegal, please check: " + maxSize); } poolConfig.setMaxPoolSize(maxSize); DynamicThreadPoolFactory.refreshThreadPool(poolConfig); } logger.info("changed max size of pool: " + poolName + ", key: " + key + ", value: " + value); } catch (RuntimeException e) { logger.error("error while changing pool, key:" + key + ", value:" + value, e); } } } for (Map.Entry<String, String> entry : queueSizeKeys.entrySet()) { String poolName = entry.getKey(); String queueSizeKey = entry.getValue(); if (key.endsWith(queueSizeKey)) { try { Integer queueSize = Integer.parseInt(value); PoolConfig poolConfig = poolConfigs.get(poolName); if (poolConfig != null) { if (queueSize < 0) { throw new IllegalArgumentException("queue size is illegal, please check: " + queueSize); } poolConfig.setWorkQueueSize(queueSize); DynamicThreadPoolFactory.refreshThreadPool(poolConfig); } logger.info("changed queue size of pool: " + poolName + ", key: " + key + ", value: " + value); } catch (RuntimeException e) { logger.error("error while changing pool, key:" + key + ", value:" + value, e); } } } } @Override public void onKeyAdded(String key, String value) { } @Override public void onKeyRemoved(String key) { } } }