/*
* Copyright 2009-2016 Weibo, Inc.
*
* 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.weibo.api.motan.transport;
import com.weibo.api.motan.common.URLParamType;
import com.weibo.api.motan.exception.MotanServiceException;
import com.weibo.api.motan.rpc.URL;
import com.weibo.api.motan.util.LoggerUtil;
import org.apache.commons.pool.BasePoolableObjectFactory;
import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool;
/**
* @author maijunsheng
* @version 创建时间:2013-6-14
*/
public abstract class AbstractPoolClient extends AbstractClient {
protected static long defaultMinEvictableIdleTimeMillis = (long) 1000 * 60 * 60;//默认链接空闲时间
protected static long defaultSoftMinEvictableIdleTimeMillis = (long) 1000 * 60 * 10;//
protected static long defaultTimeBetweenEvictionRunsMillis = (long) 1000 * 60 * 10;//默认回收周期
protected GenericObjectPool pool;
protected GenericObjectPool.Config poolConfig;
protected PoolableObjectFactory factory;
public AbstractPoolClient(URL url) {
super(url);
}
protected void initPool() {
poolConfig = new GenericObjectPool.Config();
poolConfig.minIdle =
url.getIntParameter(URLParamType.minClientConnection.getName(), URLParamType.minClientConnection.getIntValue());
poolConfig.maxIdle =
url.getIntParameter(URLParamType.maxClientConnection.getName(), URLParamType.maxClientConnection.getIntValue());
poolConfig.maxActive = poolConfig.maxIdle;
poolConfig.maxWait = url.getIntParameter(URLParamType.requestTimeout.getName(), URLParamType.requestTimeout.getIntValue());
poolConfig.lifo = url.getBooleanParameter(URLParamType.poolLifo.getName(), URLParamType.poolLifo.getBooleanValue());
poolConfig.minEvictableIdleTimeMillis = defaultMinEvictableIdleTimeMillis;
poolConfig.softMinEvictableIdleTimeMillis = defaultSoftMinEvictableIdleTimeMillis;
poolConfig.timeBetweenEvictionRunsMillis = defaultTimeBetweenEvictionRunsMillis;
factory = createChannelFactory();
pool = new GenericObjectPool(factory, poolConfig);
boolean lazyInit = url.getBooleanParameter(URLParamType.lazyInit.getName(), URLParamType.lazyInit.getBooleanValue());
if (!lazyInit) {
for (int i = 0; i < poolConfig.minIdle; i++) {
try {
pool.addObject();
} catch (Exception e) {
LoggerUtil.error("NettyClient init pool create connect Error: url=" + url.getUri(), e);
}
}
}
}
protected abstract BasePoolableObjectFactory createChannelFactory();
protected Channel borrowObject() throws Exception {
Channel nettyChannel = (Channel) pool.borrowObject();
if (nettyChannel != null && nettyChannel.isAvailable()) {
return nettyChannel;
}
invalidateObject(nettyChannel);
String errorMsg = this.getClass().getSimpleName() + " borrowObject Error: url=" + url.getUri();
LoggerUtil.error(errorMsg);
throw new MotanServiceException(errorMsg);
}
protected void invalidateObject(Channel nettyChannel) {
if (nettyChannel == null) {
return;
}
try {
pool.invalidateObject(nettyChannel);
} catch (Exception ie) {
LoggerUtil.error(this.getClass().getSimpleName() + " invalidate client Error: url=" + url.getUri(), ie);
}
}
protected void returnObject(Channel channel) {
if (channel == null) {
return;
}
try {
pool.returnObject(channel);
} catch (Exception ie) {
LoggerUtil.error(this.getClass().getSimpleName() + " return client Error: url=" + url.getUri(), ie);
}
}
}