void stopRandomServer() throws Exception {
      lock.writeLock().lock();
      TestRpcServer rpcServer = null;
      try {
        if (rpcServers.size() <= minServers) {
          return;
        }
        int size = rpcServers.size();
        int rand = random.nextInt(size);
        rpcServer = serverList.remove(rand);
        InetSocketAddress address = rpcServer.getListenerAddress();
        if (address == null) {
          // Throw exception here. We can't remove this instance from the server map because
          // we no longer have access to its map key
          throw new IOException("Listener channel is closed");
        }
        rpcServers.remove(address);

        if (rpcServer != null) {
          stopServer(rpcServer);
        }
      } finally {
        lock.writeLock().unlock();
      }
    }
    @Override
    public void run() {
      while (running.get()) {
        boolean isBigPayload = random.nextBoolean();
        String message = isBigPayload ? BIG_PAYLOAD : id + numCalls;
        EchoRequestProto param = EchoRequestProto.newBuilder().setMessage(message).build();
        EchoResponseProto ret;
        TestRpcServer server = cluster.getRandomServer();
        try {
          sending.set(true);
          BlockingInterface stub = newBlockingStub(rpcClient, server.getListenerAddress());
          ret = stub.echo(null, param);
        } catch (Exception e) {
          LOG.warn(e);
          continue; // expected in case connection is closing or closed
        }

        try {
          assertNotNull(ret);
          assertEquals(message, ret.getMessage());
        } catch (Throwable t) {
          exception.compareAndSet(null, t);
        }

        numCalls++;
      }
    }
 void stopServer(TestRpcServer rpcServer) throws InterruptedException {
   InetSocketAddress address = rpcServer.getListenerAddress();
   LOG.info("Stopping server: " + address);
   rpcServer.stop();
   rpcServer.join();
   LOG.info("Stopped server: " + address);
 }
    TestRpcServer startServer() throws IOException {
      lock.writeLock().lock();
      try {
        if (rpcServers.size() >= maxServers) {
          return null;
        }

        TestRpcServer rpcServer = new TestRpcServer(conf);
        rpcServer.start();
        InetSocketAddress address = rpcServer.getListenerAddress();
        if (address == null) {
          throw new IOException("Listener channel is closed");
        }
        rpcServers.put(address, rpcServer);
        serverList.add(rpcServer);
        LOG.info("Started server: " + address);
        return rpcServer;
      } finally {
        lock.writeLock().unlock();
      }
    }