use of com.alipay.remoting.Connection in project sofa-rpc by sofastack.
the class ReuseBoltClientConnectionManagerTest method testAll.
@Test
public void testAll() throws Exception {
ReuseBoltClientConnectionManager manager = new ReuseBoltClientConnectionManager(false);
Connection connection = manager.getConnection(null, null, null);
Assert.assertNull(connection);
connection = manager.getConnection(rpcClient, null, null);
Assert.assertNull(connection);
ClientTransportConfig wrongConfig = buildConfig(12224);
connection = manager.getConnection(rpcClient, wrongConfig, null);
Assert.assertNull(connection);
// 连不上的端口
Connection result = manager.getConnection(rpcClient, wrongConfig, buildUrl(wrongConfig));
Assert.assertNull(result);
// ok
final ClientTransportConfig config = buildConfig(12222);
connection = manager.getConnection(rpcClient, config, buildUrl(config));
Assert.assertNotNull(connection);
Assert.assertTrue(manager.urlConnectionMap.size() == 1);
Assert.assertTrue(manager.connectionRefCounter.size() == 1);
Assert.assertTrue(manager.connectionRefCounter.get(connection).get() == 1);
// 同一个config去get,计数器不增加
Connection connection1 = manager.getConnection(rpcClient, config, buildUrl(config));
Assert.assertNotNull(connection1);
Assert.assertTrue(manager.urlConnectionMap.size() == 1);
Assert.assertTrue(manager.connectionRefCounter.size() == 1);
Assert.assertTrue(connection == connection1);
Assert.assertTrue(manager.connectionRefCounter.get(connection).get() == 1);
Assert.assertTrue(manager.connectionRefCounter.get(connection1).get() == 1);
// 相同地址的config去get,计数器加一
final ClientTransportConfig config2 = buildConfig(12222);
Connection connection2 = manager.getConnection(rpcClient, config2, buildUrl(config2));
Assert.assertNotNull(connection2);
Assert.assertTrue(manager.urlConnectionMap.size() == 2);
Assert.assertTrue(manager.connectionRefCounter.size() == 1);
Assert.assertTrue(connection1 == connection2);
Assert.assertTrue(manager.connectionRefCounter.get(connection).get() == 2);
Assert.assertTrue(manager.connectionRefCounter.get(connection2).get() == 2);
// 不同地址的config去get,地址和计数器加1
ClientTransportConfig config3 = buildConfig(12223);
Connection connection3 = manager.getConnection(rpcClient, config3, buildUrl(config3));
Assert.assertNotNull(connection3);
Assert.assertFalse(connection == connection3);
Assert.assertTrue(manager.urlConnectionMap.size() == 3);
Assert.assertTrue(manager.connectionRefCounter.size() == 2);
Assert.assertTrue(manager.connectionRefCounter.get(connection).get() == 2);
Assert.assertTrue(manager.connectionRefCounter.get(connection3).get() == 1);
// 非法关闭
manager.closeConnection(null, null, null);
Assert.assertTrue(manager.urlConnectionMap.size() == 3);
manager.closeConnection(rpcClient, null, null);
Assert.assertTrue(manager.urlConnectionMap.size() == 3);
manager.closeConnection(rpcClient, config, null);
Assert.assertTrue(manager.urlConnectionMap.size() == 3);
// 正常关闭1
manager.closeConnection(rpcClient, config, buildUrl(config));
Assert.assertTrue(manager.connectionRefCounter.get(connection).get() == 1);
// 重复关闭1
manager.closeConnection(rpcClient, config, buildUrl(config));
Assert.assertTrue(manager.urlConnectionMap.size() == 2);
Assert.assertTrue(manager.connectionRefCounter.size() == 2);
Assert.assertTrue(manager.connectionRefCounter.get(connection).get() == 1);
// 正常关闭2
manager.closeConnection(rpcClient, config2, buildUrl(config2));
Assert.assertTrue(manager.urlConnectionMap.size() == 1);
Assert.assertTrue(manager.connectionRefCounter.size() == 1);
// 正常关闭3
manager.closeConnection(rpcClient, config3, buildUrl(config3));
Assert.assertTrue(manager.urlConnectionMap.size() == 0);
Assert.assertTrue(manager.connectionRefCounter.size() == 0);
// 检查泄漏
manager.checkLeak();
Assert.assertTrue(CommonUtils.isEmpty(manager.urlConnectionMap));
Assert.assertTrue(CommonUtils.isEmpty(manager.connectionRefCounter));
}
use of com.alipay.remoting.Connection in project sofa-rpc by sofastack.
the class ReuseBoltClientConnectionManagerTest method testConcurrentCreate.
@Test
public void testConcurrentCreate() throws Exception {
final ReuseBoltClientConnectionManager manager = new ReuseBoltClientConnectionManager(false);
final ClientTransportConfig config = buildConfig(12222);
// 并发创建
final CountDownLatch latch = new CountDownLatch(5);
List<Thread> threads = new ArrayList<Thread>(5);
final Url url = buildUrl(config);
for (int i = 0; i < 5; i++) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
Connection innerConnection = manager.getConnection(rpcClient, config, url);
System.out.println("url=" + url + ",connection=" + innerConnection);
} catch (Exception e) {
e.printStackTrace();
} finally {
latch.countDown();
}
}
}, "thread" + i);
threads.add(thread);
}
for (Thread thread : threads) {
thread.start();
}
latch.await(5000, TimeUnit.MILLISECONDS);
Assert.assertEquals(1, manager.urlConnectionMap.size());
Assert.assertEquals(1, manager.connectionRefCounter.size());
Connection connection = manager.getConnection(rpcClient, config, url);
Assert.assertNotNull(connection);
final AtomicInteger atomicInteger = manager.connectionRefCounter.get(connection);
Assert.assertEquals(1, atomicInteger.get());
// 检查泄漏
manager.checkLeak();
Assert.assertTrue(CommonUtils.isEmpty(manager.urlConnectionMap));
Assert.assertTrue(CommonUtils.isEmpty(manager.connectionRefCounter));
}
use of com.alipay.remoting.Connection in project sofa-rpc by sofastack.
the class ReuseBoltClientConnectionManager method closeConnection.
/**
* 关闭长连接
*
* @param rpcClient bolt客户端
* @param transportConfig 传输层配置
* @param url 传输层地址
*/
@Override
public void closeConnection(RpcClient rpcClient, ClientTransportConfig transportConfig, Url url) {
if (rpcClient == null || transportConfig == null || url == null) {
return;
}
// 先删除
Connection connection = urlConnectionMap.remove(transportConfig);
if (connection == null) {
return;
}
// 再判断是否需要关闭
boolean needDestroy;
AtomicInteger integer = connectionRefCounter.get(connection);
if (integer == null) {
needDestroy = true;
} else {
// 当前连接引用数
int currentCount = integer.decrementAndGet();
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Client transport {} of {} , current ref count is: {}", url.toString(), NetUtils.channelToString(connection.getLocalAddress(), connection.getRemoteAddress()), currentCount);
}
if (currentCount <= 0) {
// 此长连接无任何引用,可以销毁
connectionRefCounter.remove(connection);
needDestroy = true;
} else {
needDestroy = false;
}
}
if (needDestroy) {
rpcClient.closeStandaloneConnection(connection);
}
}
use of com.alipay.remoting.Connection in project sofa-rpc by sofastack.
the class ReuseBoltClientConnectionManager method getConnection.
/**
* 通过配置获取长连接
*
* @param rpcClient bolt客户端
* @param transportConfig 传输层配置
* @param url 传输层地址
* @return 长连接
*/
@Override
public Connection getConnection(RpcClient rpcClient, ClientTransportConfig transportConfig, Url url) {
if (rpcClient == null || transportConfig == null || url == null) {
return null;
}
Connection connection = urlConnectionMap.get(transportConfig);
if (connection != null && !connection.isFine()) {
closeConnection(rpcClient, transportConfig, url);
connection = null;
}
if (connection == null) {
try {
connection = rpcClient.getConnection(url, url.getConnectTimeout());
} catch (Exception e) {
LOGGER.warn("get connection failed in url," + url);
}
if (connection == null) {
return null;
}
// 保存唯一长连接
Connection oldConnection = urlConnectionMap.putIfAbsent(transportConfig, connection);
if (oldConnection != null) {
if (LOGGER.isWarnEnabled()) {
LOGGER.warn("Multiple threads init ClientTransport with same key:" + url);
}
// only if new connection is not equals old connection,we can close it
if (connection != oldConnection) {
// 如果同时有人插入,则使用第一个
rpcClient.closeStandaloneConnection(connection);
connection = oldConnection;
}
} else {
// 增加计数器
AtomicInteger counter = connectionRefCounter.get(connection);
if (counter == null) {
counter = new AtomicInteger(0);
AtomicInteger oldCounter = connectionRefCounter.putIfAbsent(connection, counter);
if (oldCounter != null) {
counter = oldCounter;
}
}
int currentCount = counter.incrementAndGet();
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Bolt client transport {} of {}, current ref count is: {}", url.toString(), NetUtils.channelToString(connection.getLocalAddress(), connection.getRemoteAddress()), currentCount);
}
}
}
return connection;
}
Aggregations