From 16c4c49e94f54a8cdcdb84b7bfabdf833a5b4757 Mon Sep 17 00:00:00 2001 From: Eric Anderson Date: Thu, 22 Oct 2015 12:47:34 -0700 Subject: [PATCH] Fix flake in ManagedChannelImplTest.transportFailsOnStart The scheduling on another thread led to a race where sometimes the future wasn't completed by the time isDone() was checked in ClientCallImpl causing the usage of DelayedStream, which really messed up what the test was trying to do. --- .../java/io/grpc/internal/TransportSet.java | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/core/src/main/java/io/grpc/internal/TransportSet.java b/core/src/main/java/io/grpc/internal/TransportSet.java index 9d7effe18b..ea80353fec 100644 --- a/core/src/main/java/io/grpc/internal/TransportSet.java +++ b/core/src/main/java/io/grpc/internal/TransportSet.java @@ -150,16 +150,7 @@ final class TransportSet { Preconditions.checkState(!shutdown, "Already shut down"); Preconditions.checkState(reconnectTask == null || reconnectTask.isDone(), "previous reconnectTask is not done"); - long delayMillis; - if (reconnectPolicy == null) { - // First connect attempt - delayMillis = 0; - reconnectPolicy = backoffPolicyProvider.get(); - } else { - // Reconnect attempts - delayMillis = reconnectPolicy.nextBackoffMillis(); - } - reconnectTask = scheduledExecutor.schedule(new Runnable() { + Runnable createTransportRunnable = new Runnable() { @Override public void run() { synchronized (lock) { @@ -177,7 +168,18 @@ final class TransportSet { "failed to set the new transport to the future"); } } - }, delayMillis, TimeUnit.MILLISECONDS); + }; + if (reconnectPolicy == null) { + // First connect attempt + reconnectPolicy = backoffPolicyProvider.get(); + createTransportRunnable.run(); + reconnectTask = null; + } else { + // Reconnect attempts + long delayMillis = reconnectPolicy.nextBackoffMillis(); + reconnectTask = scheduledExecutor.schedule( + createTransportRunnable, delayMillis, TimeUnit.MILLISECONDS); + } } /** @@ -196,7 +198,9 @@ final class TransportSet { if (transports.isEmpty()) { runCallback = true; } - reconnectTask.cancel(false); + if (reconnectTask != null) { + reconnectTask.cancel(false); + } // else: the callback will be run once all transports have been terminated } if (savedActiveTransportFuture != null) {