package io.craft.atom.rpc; import io.craft.atom.rpc.api.RpcParameter; import io.craft.atom.rpc.spi.RpcApi; import io.craft.atom.rpc.spi.RpcExecutorFactory; import io.craft.atom.rpc.spi.RpcRegistry; import io.craft.atom.util.thread.MonitoringExecutorService; import io.craft.atom.util.thread.NamedThreadFactory; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import lombok.Getter; import lombok.Setter; /** * @author mindwind * @version 1.0, Aug 12, 2014 */ public class DefaultRpcExecutorFactory implements RpcExecutorFactory { @Getter @Setter private RpcRegistry registry; @Getter @Setter private Map<String, MonitoringExecutorService> pool ; // ~ ------------------------------------------------------------------------------------------------------------ public DefaultRpcExecutorFactory() { this.pool = new ConcurrentHashMap<String, MonitoringExecutorService>(); } // ~ ------------------------------------------------------------------------------------------------------------ @Override public MonitoringExecutorService getExecutor(RpcApi api) { return getExecutor0(api); } private MonitoringExecutorService getExecutor0(RpcApi queryApi) { String key = queryApi.getKey(); MonitoringExecutorService es = pool.get(key); if (es == null) { synchronized (this) { if (es == null) { RpcApi api = registry.lookup(queryApi); if (api == null) { throw new RpcException(RpcException.SERVER_ERROR, "No exported api mapping"); } RpcParameter parameter = api.getRpcParameter(); int threads = parameter.getRpcThreads() == 0 ? 1 : parameter.getRpcThreads(); int queues = parameter.getRpcQueues() == 0 ? 1 : parameter.getRpcQueues() ; RpcThreadPoolExecutor tpe = new RpcThreadPoolExecutor(threads, threads, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(queues), new NamedThreadFactory("craft-atom-rpc")); tpe.allowCoreThreadTimeOut(true); es = tpe; pool.put(key, tpe); } } } return es; } @Override public void shutdown() { for (MonitoringExecutorService mes : pool.values()) { mes.shutdownNow(); } } }