Пример #1
0
  /**
   * Forcefully shuts down the connection to this tablet server and fails all the outstanding RPCs.
   * Only use when shutting down a client.
   *
   * @return deferred object to use to track the shutting down of this connection
   */
  public Deferred<Void> shutdown() {
    // First, check whether we have RPCs in flight and cancel them.
    for (Iterator<KuduRpc<?>> ite = rpcs_inflight.values().iterator(); ite.hasNext(); ) {
      KuduRpc<?> rpc = ite.next();
      rpc.errback(new ConnectionResetException(null));
      ite.remove();
    }

    // Same for the pending RPCs.
    synchronized (this) {
      if (pending_rpcs != null) {
        for (Iterator<KuduRpc<?>> ite = pending_rpcs.iterator(); ite.hasNext(); ) {
          ite.next().errback(new ConnectionResetException(null));
          ite.remove();
        }
      }
    }

    final Channel chancopy = chan;
    if (chancopy == null) {
      return Deferred.fromResult(null);
    }
    if (chancopy.isConnected()) {
      Channels.disconnect(chancopy); // ... this is going to set it to null.
      // At this point, all in-flight RPCs are going to be failed.
    }
    if (chancopy.isBound()) {
      Channels.unbind(chancopy);
    }
    // It's OK to call close() on a Channel if it's already closed.
    final ChannelFuture future = Channels.close(chancopy);
    // Now wrap the ChannelFuture in a Deferred.
    final Deferred<Void> d = new Deferred<Void>();
    // Opportunistically check if it's already completed successfully.
    if (future.isSuccess()) {
      d.callback(null);
    } else {
      // If we get here, either the future failed (yeah, that sounds weird)
      // or the future hasn't completed yet (heh).
      future.addListener(
          new ChannelFutureListener() {
            public void operationComplete(final ChannelFuture future) {
              if (future.isSuccess()) {
                d.callback(null);
                return;
              }
              final Throwable t = future.getCause();
              if (t instanceof Exception) {
                d.callback(t);
              } else {
                // Wrap the Throwable because Deferred doesn't handle Throwables,
                // it only uses Exception.
                d.callback(
                    new NonRecoverableException("Failed to shutdown: " + TabletClient.this, t));
              }
            }
          });
    }
    return d;
  }