Example #1
0
 /**
  * Initiates an orderly shutdown in which preexisting calls continue but new calls are immediately
  * cancelled.
  */
 public ChannelImpl shutdown() {
   ClientTransport savedActiveTransport;
   synchronized (lock) {
     if (shutdown) {
       return this;
     }
     shutdown = true;
     // After shutdown there are no new calls, so no new cancellation tasks are needed
     scheduledExecutor = SharedResourceHolder.release(TIMER_SERVICE, scheduledExecutor);
     savedActiveTransport = activeTransport;
     if (savedActiveTransport != null) {
       activeTransport = null;
     } else if (transports.isEmpty()) {
       terminated = true;
       lock.notifyAll();
       if (terminationRunnable != null) {
         terminationRunnable.run();
       }
     }
   }
   if (savedActiveTransport != null) {
     savedActiveTransport.shutdown();
   }
   return this;
 }
Example #2
0
  private ClientTransport obtainActiveTransport() {
    ClientTransport savedActiveTransport = activeTransport;
    // If we know there is an active transport and we are not in backoff mode, return quickly.
    if (savedActiveTransport != null && !(savedActiveTransport instanceof InactiveTransport)) {
      return savedActiveTransport;
    }
    synchronized (lock) {
      if (shutdown) {
        return null;
      }
      savedActiveTransport = activeTransport;
      if (savedActiveTransport instanceof InactiveTransport) {
        if (System.nanoTime() > TimeUnit.MILLISECONDS.toNanos(reconnectTimeMillis)) {
          // The timeout expired, clear the inactive transport and update the shutdown status to
          // something that is retryable.
          activeTransport = null;
          savedActiveTransport = activeTransport;
        } else {
          // We are still in backoff mode, just return the inactive transport.
          return savedActiveTransport;
        }
      }

      if (savedActiveTransport != null) {
        return savedActiveTransport;
      }
      // There is no active transport, or we just finished backoff.  Create a new transport.
      ClientTransport newActiveTransport = transportFactory.newClientTransport();
      transports.add(newActiveTransport);
      boolean failed = true;
      try {
        newActiveTransport.start(new TransportListener(newActiveTransport));
        failed = false;
      } finally {
        if (failed) {
          transports.remove(newActiveTransport);
        }
      }
      // It's possible that start() called transportShutdown() and transportTerminated(). If so, we
      // wouldn't want to make it the active transport.
      if (transports.contains(newActiveTransport)) {
        // start() must return before we set activeTransport, since activeTransport is accessed
        // without a lock.
        activeTransport = newActiveTransport;
      }
      return newActiveTransport;
    }
  }