From 389c5403e90d44ae0f8c65bdac51579a1fed8299 Mon Sep 17 00:00:00 2001 From: Chengyuan Zhang Date: Wed, 13 Jan 2021 17:01:02 -0800 Subject: [PATCH] core: make subchannel creation timing restriction stricter (#7790) Throw for subchannel creation if the channel is being shutting down and the delayed transport is terminated (aka, all retry calls has been finished). This enforces load balancer implementations to avoid creating subchannels after being shut down. --- .../io/grpc/internal/ManagedChannelImpl.java | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java b/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java index f9e3ba7fd20..fb9e3bb9f01 100644 --- a/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java +++ b/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java @@ -1391,12 +1391,8 @@ private class LbHelperImpl extends LoadBalancer.Helper { @Override public AbstractSubchannel createSubchannel(CreateSubchannelArgs args) { syncContext.throwIfNotInThisSynchronizationContext(); - return createSubchannelInternal(args); - } - - private SubchannelImpl createSubchannelInternal(CreateSubchannelArgs args) { - // TODO(ejona): can we be even stricter? Like loadBalancer == null? - checkState(!terminated, "Channel is terminated"); + // No new subchannel should be created after load balancer has been shutdown. + checkState(!terminating, "Channel is being terminated"); return new SubchannelImpl(args, this); } @@ -1823,18 +1819,8 @@ private final class SubchannelImpl extends AbstractSubchannel { private void internalStart(final SubchannelStateListener listener) { checkState(!started, "already started"); checkState(!shutdown, "already shutdown"); + checkState(!terminating, "Channel is being terminated"); started = true; - // TODO(zhangkun): possibly remove the volatile of terminating when this whole method is - // required to be called from syncContext - if (terminating) { - syncContext.execute(new Runnable() { - @Override - public void run() { - listener.onSubchannelState(ConnectivityStateInfo.forNonError(SHUTDOWN)); - } - }); - return; - } final class ManagedInternalSubchannelCallback extends InternalSubchannel.Callback { // All callbacks are run in syncContext @Override