/* * Copyright(C) 2010-2011 Alibaba Group Holding Limited All rights reserved. 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.alibaba.doris.dataserver.migrator.connection; import java.net.InetSocketAddress; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.locks.ReentrantLock; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.doris.client.net.Connection; import com.alibaba.doris.client.net.NetException; import com.alibaba.doris.common.route.MigrationRoutePair; /** * MigrationConnectionManager * * @author Kun He (Raymond He), kun.hek@alibaba-inc.com * @since 1.0 2011-6-1 */ public class MigrationConnectionManager implements ConnectionManager { private static final Logger logger = LoggerFactory.getLogger(MigrationConnectionManager.class); protected Map<String, Connection> connections = new HashMap<String, Connection>(); protected volatile boolean ok = false; protected ReentrantLock lock = new ReentrantLock(); /** * 初始化一组连接 * * @param routePairs */ public MigrationConnectionManager() { } /** * @param routePairs */ public void connect(List<MigrationRoutePair> routePairs) { lock.lock(); try { connect0(routePairs); logConnection(); } catch (Exception e) { logger.error("Fail to create migration connection manager, and give up migration. Cause:" + e); close(); throw new NetException(e); } finally { lock.unlock(); } } /** * @param routePairs */ void connect0(List<MigrationRoutePair> routePairs) { if (logger.isDebugEnabled()) logger.debug("Prepare to get migrate connections. "); for (int i = 0; i < routePairs.size(); i++) { MigrationRoutePair routePair = routePairs.get(i); String[] pId = routePair.getTargetPhysicalId().split(":"); String ip = pId[0]; int port = Integer.valueOf(pId[1]).intValue(); // 和目标机器建立连接 InetSocketAddress address = new InetSocketAddress(ip, port); String adsKey = address.toString(); adsKey = adsKey.startsWith("/") ? adsKey.substring(1) : adsKey; Connection connection = null; if (logger.isDebugEnabled()) logger.debug("VNode " + routePair.getVnode() + ",Target address: " + adsKey); if (!connections.containsKey(adsKey)) { createConnection(address, adsKey); } else { connection = connections.get(adsKey); if (!connection.isConnected()) { connection.close(); connection = null; createConnection(address, adsKey); } } } ok = true; } protected void createConnection(InetSocketAddress address, String adsKey) { Connection connection; connection = createConnection(address); connections.put(adsKey, connection); if (logger.isDebugEnabled()) logger.debug("Create a migrate connection " + adsKey); } /** * 创建到Target Node的实际的物理连接 * * @param address * @return */ protected Connection createConnection(InetSocketAddress address) { Connection connection = new ThreadLocalConnection(address); return connection; } private void logConnection() { if (logger.isInfoEnabled()) { logger.info("Succeed to get migrate connections. Connections: " + connections.size()); int i = 0; Iterator<String> itor = connections.keySet().iterator(); while (itor.hasNext()) { String cnKey = itor.next(); logger.info("No." + (i++) + ": migration Connection:" + cnKey); } } } /** * (non-Javadoc) * * @see com.alibaba.doris.dataserver.migrator.connection.ConnectionManager#getConnection(java.net.InetSocketAddress) */ public Connection getConnection(String address) { lock.lock(); try { return connections.get(address); } finally { lock.unlock(); } } public boolean isOpen() { lock.lock(); try { return ok; } finally { lock.unlock(); } } /** * 关闭连接 */ public void close() { lock.lock(); try { close0(); } finally { lock.unlock(); } } /** * 释放所有连接 */ public void close0() { for (Entry<String, Connection> entry : connections.entrySet()) { Connection connection = entry.getValue(); if (connection != null) { connection.close(); if (logger.isDebugEnabled()) logger.debug("Migrate connection closed: " + connection); } } connections.clear(); if (logger.isDebugEnabled()) logger.debug("Migrate connection manager clear all connections"); ok = false; } public void sleep(long time) { try { Thread.sleep(time); } catch (InterruptedException e) { } } }