6060import java .util .concurrent .TimeUnit ;
6161import java .util .logging .Level ;
6262import java .util .logging .Logger ;
63+ import javax .annotation .Nullable ;
6364import javax .annotation .concurrent .GuardedBy ;
6465import okio .Buffer ;
6566import okio .BufferedSource ;
@@ -73,6 +74,9 @@ final class OkHttpServerTransport implements ServerTransport,
7374 ExceptionHandlingFrameWriter .TransportExceptionHandler , OutboundFlowController .Transport {
7475 private static final Logger log = Logger .getLogger (OkHttpServerTransport .class .getName ());
7576 private static final int GRACEFUL_SHUTDOWN_PING = 0x1111 ;
77+
78+ private static final long GRACEFUL_SHUTDOWN_PING_TIMEOUT_NANOS = TimeUnit .SECONDS .toNanos (1 );
79+
7680 private static final int KEEPALIVE_PING = 0xDEAD ;
7781 private static final ByteString HTTP_METHOD = ByteString .encodeUtf8 (":method" );
7882 private static final ByteString CONNECT_METHOD = ByteString .encodeUtf8 ("CONNECT" );
@@ -132,6 +136,8 @@ final class OkHttpServerTransport implements ServerTransport,
132136 /** Non-{@code null} when waiting for forceful close GOAWAY to be sent. */
133137 @ GuardedBy ("lock" )
134138 private ScheduledFuture <?> forcefulCloseTimer ;
139+ @ GuardedBy ("lock" )
140+ private Long gracefulShutdownPeriod = null ;
135141
136142 public OkHttpServerTransport (Config config , Socket bareSocket ) {
137143 this .config = Preconditions .checkNotNull (config , "config" );
@@ -250,15 +256,16 @@ public void data(boolean outFinished, int streamId, Buffer source, int byteCount
250256
251257 @ Override
252258 public void shutdown () {
253- shutdown (TimeUnit . SECONDS . toNanos ( 1L ) );
259+ shutdown (null );
254260 }
255261
256- private void shutdown (Long graceTimeInNanos ) {
262+ private void shutdown (@ Nullable Long gracefulShutdownPeriod ) {
257263 synchronized (lock ) {
258264 if (gracefulShutdown || abruptShutdown ) {
259265 return ;
260266 }
261267 gracefulShutdown = true ;
268+ this .gracefulShutdownPeriod = gracefulShutdownPeriod ;
262269 if (frameWriter == null ) {
263270 handshakeShutdown = true ;
264271 GrpcUtil .closeQuietly (bareSocket );
@@ -267,7 +274,8 @@ private void shutdown(Long graceTimeInNanos) {
267274 // we also set a timer to limit the upper bound in case the PING is excessively stalled or
268275 // the client is malicious.
269276 secondGoawayTimer = scheduledExecutorService .schedule (
270- this ::triggerGracefulSecondGoaway , graceTimeInNanos , TimeUnit .NANOSECONDS );
277+ this ::triggerGracefulSecondGoaway ,
278+ GRACEFUL_SHUTDOWN_PING_TIMEOUT_NANOS , TimeUnit .NANOSECONDS );
271279 frameWriter .goAway (Integer .MAX_VALUE , ErrorCode .NO_ERROR , new byte [0 ]);
272280 frameWriter .ping (false , 0 , GRACEFUL_SHUTDOWN_PING );
273281 frameWriter .flush ();
@@ -289,6 +297,10 @@ private void triggerGracefulSecondGoaway() {
289297 } else {
290298 frameWriter .flush ();
291299 }
300+ if (gracefulShutdownPeriod != null ) {
301+ forcefulCloseTimer = scheduledExecutorService .schedule (
302+ this ::triggerForcefulClose , gracefulShutdownPeriod , TimeUnit .NANOSECONDS );
303+ }
292304 }
293305 }
294306
0 commit comments