@Override
  public void stop() {
    logger.info("Avro source {} stopping: {}", getName(), this);

    server.close();

    try {
      server.join();
    } catch (InterruptedException e) {
      logger.info(
          "Avro source "
              + getName()
              + ": Interrupted while waiting "
              + "for Avro server to stop. Exiting. Exception follows.",
          e);
    }
    sourceCounter.stop();
    connectionCountUpdater.shutdown();
    while (!connectionCountUpdater.isTerminated()) {
      try {
        Thread.sleep(100);
      } catch (InterruptedException ex) {
        logger.error(
            "Interrupted while waiting for connection count executor " + "to terminate", ex);
        Throwables.propagate(ex);
      }
    }
    super.stop();
    logger.info("Avro source {} stopped. Metrics: {}", getName(), sourceCounter);
  }
  @Override
  public void start() {
    logger.info("Starting {}...", this);

    Responder responder = new SpecificResponder(AvroSourceProtocol.class, this);
    if (maxThreads <= 0) {
      server = new NettyServer(responder, new InetSocketAddress(bindAddress, port));
    } else {
      server =
          new NettyServer(
              responder,
              new InetSocketAddress(bindAddress, port),
              new NioServerSocketChannelFactory(
                  Executors.newCachedThreadPool(), Executors.newFixedThreadPool(maxThreads)));
    }
    connectionCountUpdater = Executors.newSingleThreadScheduledExecutor();
    server.start();
    sourceCounter.start();
    super.start();
    final NettyServer srv = (NettyServer) server;
    connectionCountUpdater.scheduleWithFixedDelay(
        new Runnable() {

          @Override
          public void run() {
            sourceCounter.setOpenConnectionCount(Long.valueOf(srv.getNumActiveConnections()));
          }
        },
        0,
        60,
        TimeUnit.SECONDS);

    logger.info("Avro source {} started.", getName());
  }