Skip to content

Commit c08d74f

Browse files
committed
TransportSet shutdown() also shuts down the pending transport.
Previously TransportSet.shutdown() only shuts down the active transport, which means a transport will not be shutdown if it's not ready yet. This issue was introduced by grpc#1494 that postponed the assignment of the active transport till transport ready.
1 parent 9f37951 commit c08d74f

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

core/src/main/java/io/grpc/internal/TransportSet.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@ final class TransportSet implements WithLogId {
102102
private final Collection<ManagedClientTransport> transports =
103103
new ArrayList<ManagedClientTransport>();
104104

105+
/**
106+
* The to-be active transport, which is not ready yet.
107+
*/
108+
@GuardedBy("lock")
109+
@Nullable
110+
private ManagedClientTransport pendingTransport;
111+
105112
private final LoadBalancer<ClientTransport> loadBalancer;
106113

107114
@GuardedBy("lock")
@@ -194,6 +201,7 @@ private void startNewTransport(DelayedClientTransport delayedTransport) {
194201
log.log(Level.FINE, "[{0}] Created {1} for {2}",
195202
new Object[] {getLogId(), transport.getLogId(), address});
196203
}
204+
pendingTransport = transport;
197205
transports.add(transport);
198206
transport.start(new TransportListener(transport, delayedTransport, address));
199207
}
@@ -257,6 +265,7 @@ public ClientTransport get() {
257265
*/
258266
final void shutdown() {
259267
ManagedClientTransport savedActiveTransport;
268+
ManagedClientTransport savedPendingTransport;
260269
boolean runCallback = false;
261270
synchronized (lock) {
262271
if (shutdown) {
@@ -265,6 +274,7 @@ final void shutdown() {
265274
// Transition to SHUTDOWN
266275
shutdown = true;
267276
savedActiveTransport = activeTransport;
277+
savedPendingTransport = pendingTransport;
268278
activeTransport = null;
269279
if (transports.isEmpty()) {
270280
runCallback = true;
@@ -274,6 +284,9 @@ final void shutdown() {
274284
if (savedActiveTransport != null) {
275285
savedActiveTransport.shutdown();
276286
}
287+
if (savedPendingTransport != null) {
288+
savedPendingTransport.shutdown();
289+
}
277290
if (runCallback) {
278291
callback.onTerminated();
279292
}
@@ -358,7 +371,9 @@ public void transportReady() {
358371
"Unexpected non-null activeTransport");
359372
} else if (activeTransport == delayedTransport) {
360373
// Transition to READY
374+
Preconditions.checkState(pendingTransport == transport, "transport mismatch");
361375
activeTransport = transport;
376+
pendingTransport = null;
362377
}
363378
}
364379
delayedTransport.setTransport(transport);

core/src/test/java/io/grpc/internal/TransportSetTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,22 @@ public void shutdownBeforeTransportCreatedWithoutPendingStream() throws Exceptio
498498
assertEquals(0, transports.size());
499499
}
500500

501+
@Test
502+
public void shutdownBeforeTransportReady() throws Exception {
503+
SocketAddress addr = mock(SocketAddress.class);
504+
createTransportSet(addr);
505+
506+
ClientTransport pick = transportSet.obtainActiveTransport();
507+
MockClientTransportInfo transportInfo = transports.poll();
508+
assertNotSame(transportInfo.transport, pick);
509+
510+
// Shutdown the TransportSet before the pending transport is ready
511+
transportSet.shutdown();
512+
513+
// The transport should've been shut down even though it's not the active transport yet.
514+
verify(transportInfo.transport).shutdown();
515+
}
516+
501517
@Test
502518
public void obtainTransportAfterShutdown() throws Exception {
503519
SocketAddress addr = mock(SocketAddress.class);

0 commit comments

Comments
 (0)