1 /* 2 * Copyright 2016 The gRPC Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package io.grpc.netty; 18 19 import com.google.errorprone.annotations.CanIgnoreReturnValue; 20 import io.grpc.Status; 21 import io.grpc.internal.ManagedClientTransport; 22 23 /** Maintainer of transport lifecycle status. */ 24 final class ClientTransportLifecycleManager { 25 private final ManagedClientTransport.Listener listener; 26 private boolean transportReady; 27 private boolean transportShutdown; 28 private boolean transportInUse; 29 /** null iff !transportShutdown. */ 30 private Status shutdownStatus; 31 /** null iff !transportShutdown. */ 32 private Throwable shutdownThrowable; 33 private boolean transportTerminated; 34 ClientTransportLifecycleManager(ManagedClientTransport.Listener listener)35 public ClientTransportLifecycleManager(ManagedClientTransport.Listener listener) { 36 this.listener = listener; 37 } 38 notifyReady()39 public void notifyReady() { 40 if (transportReady || transportShutdown) { 41 return; 42 } 43 transportReady = true; 44 listener.transportReady(); 45 } 46 47 /** 48 * Marks transport as shutdown, but does not set the error status. This must eventually be 49 * followed by a call to notifyShutdown. 50 */ notifyGracefulShutdown(Status s)51 public void notifyGracefulShutdown(Status s) { 52 if (transportShutdown) { 53 return; 54 } 55 transportShutdown = true; 56 listener.transportShutdown(s); 57 } 58 59 /** Returns {@code true} if was the first shutdown. */ 60 @CanIgnoreReturnValue notifyShutdown(Status s)61 public boolean notifyShutdown(Status s) { 62 notifyGracefulShutdown(s); 63 if (shutdownStatus != null) { 64 return false; 65 } 66 shutdownStatus = s; 67 shutdownThrowable = s.asException(); 68 return true; 69 } 70 notifyInUse(boolean inUse)71 public void notifyInUse(boolean inUse) { 72 if (inUse == transportInUse) { 73 return; 74 } 75 transportInUse = inUse; 76 listener.transportInUse(inUse); 77 } 78 notifyTerminated(Status s)79 public void notifyTerminated(Status s) { 80 if (transportTerminated) { 81 return; 82 } 83 transportTerminated = true; 84 notifyShutdown(s); 85 listener.transportTerminated(); 86 } 87 getShutdownStatus()88 public Status getShutdownStatus() { 89 return shutdownStatus; 90 } 91 getShutdownThrowable()92 public Throwable getShutdownThrowable() { 93 return shutdownThrowable; 94 } 95 } 96