/**
   * Closes all opened connections.
   *
   * @param waitCompletion If {@code true} waits for all pending requests to be proceeded.
   */
  @SuppressWarnings("TooBroadScope")
  @Override
  public void stop(boolean waitCompletion) {
    Collection<GridClientConnection> closeConns;

    if (closed) return;

    // Mark manager as closed.
    closed = true;

    // Remove all connections from cache.
    closeConns = new ArrayList<>(conns.values());

    conns.clear();

    nodeConns.clear();

    // Close old connection outside the writer lock.
    for (GridClientConnection conn : closeConns) conn.close(CLIENT_CLOSED, waitCompletion);

    if (pingExecutor != null)
      GridClientUtils.shutdownNow(GridClientConnectionManager.class, pingExecutor, log);

    GridClientUtils.shutdownNow(GridClientConnectionManager.class, executor, log);

    if (srv != null) srv.stop();
  }
  /** {@inheritDoc} */
  @SuppressWarnings("BusyWait")
  @Override
  public void init(Collection<InetSocketAddress> srvs)
      throws GridClientException, InterruptedException {
    init0();

    GridClientException firstEx = null;

    for (int i = 0; i < INIT_RETRY_CNT; i++) {
      Collection<InetSocketAddress> srvsCp = new ArrayList<>(srvs);

      while (!srvsCp.isEmpty()) {
        GridClientConnection conn = null;

        try {
          conn = connect(null, srvsCp);

          conn.topology(cfg.isAutoFetchAttributes(), cfg.isAutoFetchMetrics(), null).get();

          return;
        } catch (GridServerUnreachableException e) {
          // No connection could be opened to any of initial addresses - exit to retry loop.
          assert conn == null
              : "GridClientConnectionResetException was thrown from GridClientConnection#topology";

          if (firstEx == null) firstEx = e;

          break;
        } catch (GridClientConnectionResetException e) {
          // Connection was established but topology update failed -
          // trying other initial addresses if any.
          assert conn != null : "GridClientConnectionResetException was thrown from connect()";

          if (firstEx == null) firstEx = e;

          if (!srvsCp.remove(conn.serverAddress()))
            // We have misbehaving collection or equals - just exit to avoid infinite loop.
            break;
        }
      }

      Thread.sleep(INIT_RETRY_INTERVAL);
    }

    for (GridClientConnection c : conns.values()) {
      conns.remove(c.serverAddress(), c);

      c.close(FAILED, false);
    }

    throw firstEx;
  }
  /** {@inheritDoc} */
  @Override
  public void terminateConnection(GridClientConnection conn, GridClientNode node, Throwable e) {
    if (log.isLoggable(Level.FINE))
      log.fine(
          "Connection with remote node was terminated [node="
              + node
              + ", srvAddr="
              + conn.serverAddress()
              + ", errMsg="
              + e.getMessage()
              + ']');

    closeIdle();

    conn.close(FAILED, false);
  }