/** * Returns connection to one of the given addresses. * * @param nodeId {@code UUID} of node for mapping with connection. {@code null} if no need of * mapping. * @param srvs Collection of addresses to connect to. * @return Connection to use for operations, targeted for the given node. * @throws GridServerUnreachableException If connection can't be established. * @throws GridClientClosedException If connections manager has been closed already. * @throws InterruptedException If connection was interrupted. */ public GridClientConnection connection(@Nullable UUID nodeId, Collection<InetSocketAddress> srvs) throws GridServerUnreachableException, GridClientClosedException, InterruptedException { if (srvs == null || srvs.isEmpty()) throw new GridServerUnreachableException( "Failed to establish connection to the grid" + " (address list is empty)."); checkClosed(); // Search for existent connection. for (InetSocketAddress endPoint : srvs) { assert endPoint != null; GridClientConnection conn = conns.get(endPoint); if (conn == null) continue; // Ignore closed connections. if (conn.closeIfIdle(cfg.getMaxConnectionIdleTime())) { closeIdle(); continue; } if (nodeId != null) nodeConns.put(nodeId, conn); return conn; } return connect(nodeId, srvs); }
/** * Close all connections idling for more then {@link * GridClientConfiguration#getMaxConnectionIdleTime()} milliseconds. */ @SuppressWarnings("ForLoopReplaceableByForEach") private void closeIdle() { for (Iterator<Map.Entry<UUID, GridClientConnection>> it = nodeConns.entrySet().iterator(); it.hasNext(); ) { Map.Entry<UUID, GridClientConnection> entry = it.next(); GridClientConnection conn = entry.getValue(); if (conn.closeIfIdle(cfg.getMaxConnectionIdleTime())) { conns.remove(conn.serverAddress(), conn); nodeConns.remove(entry.getKey(), conn); } } for (GridClientConnection conn : conns.values()) if (conn.closeIfIdle(cfg.getMaxConnectionIdleTime())) conns.remove(conn.serverAddress(), conn); }
/** * Gets active communication facade. * * @param node Remote node to which connection should be established. * @throws GridServerUnreachableException If none of the servers can be reached after the * exception. * @throws GridClientClosedException If client was closed manually. * @throws InterruptedException If connection was interrupted. */ @Override public GridClientConnection connection(GridClientNode node) throws GridClientClosedException, GridServerUnreachableException, InterruptedException { assert node != null; // Use router's connections if defined. if (!routers.isEmpty()) return connection(null, routers); GridClientConnection conn = nodeConns.get(node.nodeId()); if (conn != null) { // Ignore closed connections. if (conn.closeIfIdle(cfg.getMaxConnectionIdleTime())) closeIdle(); else return conn; } // Use node's connection, if node is available over rest. Collection<InetSocketAddress> endpoints = node.availableAddresses(cfg.getProtocol(), true); List<InetSocketAddress> resolvedEndpoints = new ArrayList<>(endpoints.size()); for (InetSocketAddress endpoint : endpoints) if (!endpoint.isUnresolved()) resolvedEndpoints.add(endpoint); if (resolvedEndpoints.isEmpty()) { throw new GridServerUnreachableException( "No available endpoints to connect " + "(is rest enabled for this node?): " + node); } boolean sameHost = node.attributes().isEmpty() || F.containsAny(U.allLocalMACs(), node.attribute(ATTR_MACS).toString().split(", ")); Collection<InetSocketAddress> srvs = new LinkedHashSet<>(); if (sameHost) { Collections.sort(resolvedEndpoints, U.inetAddressesComparator(true)); srvs.addAll(resolvedEndpoints); } else { for (InetSocketAddress endpoint : resolvedEndpoints) if (!endpoint.getAddress().isLoopbackAddress()) srvs.add(endpoint); } return connection(node.nodeId(), srvs); }