diff --git a/README.md b/README.md index 2c18763b180..726e51681fb 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,8 @@ For a guided tour, take a look at the [quick start guide](https://grpc.io/docs/languages/java/quickstart) or the more explanatory [gRPC basics](https://grpc.io/docs/languages/java/basics). -The [examples](https://github.com/grpc/grpc-java/tree/v1.51.0/examples) and the -[Android example](https://github.com/grpc/grpc-java/tree/v1.51.0/examples/android) +The [examples](https://github.com/grpc/grpc-java/tree/v1.51.1/examples) and the +[Android example](https://github.com/grpc/grpc-java/tree/v1.51.1/examples/android) are standalone projects that showcase the usage of gRPC. Download @@ -43,18 +43,18 @@ Download [the JARs][]. Or for Maven with non-Android, add to your `pom.xml`: io.grpc grpc-netty-shaded - 1.51.0 + 1.51.1 runtime io.grpc grpc-protobuf - 1.51.0 + 1.51.1 io.grpc grpc-stub - 1.51.0 + 1.51.1 org.apache.tomcat @@ -66,23 +66,23 @@ Download [the JARs][]. Or for Maven with non-Android, add to your `pom.xml`: Or for Gradle with non-Android, add to your dependencies: ```gradle -runtimeOnly 'io.grpc:grpc-netty-shaded:1.51.0' -implementation 'io.grpc:grpc-protobuf:1.51.0' -implementation 'io.grpc:grpc-stub:1.51.0' +runtimeOnly 'io.grpc:grpc-netty-shaded:1.51.1' +implementation 'io.grpc:grpc-protobuf:1.51.1' +implementation 'io.grpc:grpc-stub:1.51.1' compileOnly 'org.apache.tomcat:annotations-api:6.0.53' // necessary for Java 9+ ``` For Android client, use `grpc-okhttp` instead of `grpc-netty-shaded` and `grpc-protobuf-lite` instead of `grpc-protobuf`: ```gradle -implementation 'io.grpc:grpc-okhttp:1.51.0' -implementation 'io.grpc:grpc-protobuf-lite:1.51.0' -implementation 'io.grpc:grpc-stub:1.51.0' +implementation 'io.grpc:grpc-okhttp:1.51.1' +implementation 'io.grpc:grpc-protobuf-lite:1.51.1' +implementation 'io.grpc:grpc-stub:1.51.1' compileOnly 'org.apache.tomcat:annotations-api:6.0.53' // necessary for Java 9+ ``` [the JARs]: -https://search.maven.org/search?q=g:io.grpc%20AND%20v:1.51.0 +https://search.maven.org/search?q=g:io.grpc%20AND%20v:1.51.1 Development snapshots are available in [Sonatypes's snapshot repository](https://oss.sonatype.org/content/repositories/snapshots/). @@ -114,7 +114,7 @@ For protobuf-based codegen integrated with the Maven build system, you can use com.google.protobuf:protoc:3.21.7:exe:${os.detected.classifier} grpc-java - io.grpc:protoc-gen-grpc-java:1.51.0:exe:${os.detected.classifier} + io.grpc:protoc-gen-grpc-java:1.51.1:exe:${os.detected.classifier} @@ -144,7 +144,7 @@ protobuf { } plugins { grpc { - artifact = 'io.grpc:protoc-gen-grpc-java:1.51.0' + artifact = 'io.grpc:protoc-gen-grpc-java:1.51.1' } } generateProtoTasks { @@ -177,7 +177,7 @@ protobuf { } plugins { grpc { - artifact = 'io.grpc:protoc-gen-grpc-java:1.51.0' + artifact = 'io.grpc:protoc-gen-grpc-java:1.51.1' } } generateProtoTasks { diff --git a/build.gradle b/build.gradle index 0c0861d44d1..e107f7f8f13 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,7 @@ subprojects { apply plugin: "net.ltgt.errorprone" group = "io.grpc" - version = "1.51.0" // CURRENT_GRPC_VERSION + version = "1.51.1" // CURRENT_GRPC_VERSION repositories { maven { // The google mirror is less flaky than mavenCentral() diff --git a/compiler/src/test/golden/TestDeprecatedService.java.txt b/compiler/src/test/golden/TestDeprecatedService.java.txt index 6229341887a..c4ff9772c78 100644 --- a/compiler/src/test/golden/TestDeprecatedService.java.txt +++ b/compiler/src/test/golden/TestDeprecatedService.java.txt @@ -8,7 +8,7 @@ import static io.grpc.MethodDescriptor.generateFullMethodName; * */ @javax.annotation.Generated( - value = "by gRPC proto compiler (version 1.51.0)", + value = "by gRPC proto compiler (version 1.51.1)", comments = "Source: grpc/testing/compiler/test.proto") @io.grpc.stub.annotations.GrpcGenerated @java.lang.Deprecated diff --git a/compiler/src/test/golden/TestService.java.txt b/compiler/src/test/golden/TestService.java.txt index e99bb98026e..b501829d702 100644 --- a/compiler/src/test/golden/TestService.java.txt +++ b/compiler/src/test/golden/TestService.java.txt @@ -8,7 +8,7 @@ import static io.grpc.MethodDescriptor.generateFullMethodName; * */ @javax.annotation.Generated( - value = "by gRPC proto compiler (version 1.51.0)", + value = "by gRPC proto compiler (version 1.51.1)", comments = "Source: grpc/testing/compiler/test.proto") @io.grpc.stub.annotations.GrpcGenerated public final class TestServiceGrpc { diff --git a/compiler/src/testLite/golden/TestDeprecatedService.java.txt b/compiler/src/testLite/golden/TestDeprecatedService.java.txt index b783fcf00c3..252a010ad57 100644 --- a/compiler/src/testLite/golden/TestDeprecatedService.java.txt +++ b/compiler/src/testLite/golden/TestDeprecatedService.java.txt @@ -8,7 +8,7 @@ import static io.grpc.MethodDescriptor.generateFullMethodName; * */ @javax.annotation.Generated( - value = "by gRPC proto compiler (version 1.51.0)", + value = "by gRPC proto compiler (version 1.51.1)", comments = "Source: grpc/testing/compiler/test.proto") @io.grpc.stub.annotations.GrpcGenerated @java.lang.Deprecated diff --git a/compiler/src/testLite/golden/TestService.java.txt b/compiler/src/testLite/golden/TestService.java.txt index 8f2c0e5a0c0..be005aaed46 100644 --- a/compiler/src/testLite/golden/TestService.java.txt +++ b/compiler/src/testLite/golden/TestService.java.txt @@ -8,7 +8,7 @@ import static io.grpc.MethodDescriptor.generateFullMethodName; * */ @javax.annotation.Generated( - value = "by gRPC proto compiler (version 1.51.0)", + value = "by gRPC proto compiler (version 1.51.1)", comments = "Source: grpc/testing/compiler/test.proto") @io.grpc.stub.annotations.GrpcGenerated public final class TestServiceGrpc { diff --git a/core/src/main/java/io/grpc/internal/GrpcUtil.java b/core/src/main/java/io/grpc/internal/GrpcUtil.java index 735b43d5f42..668d3f6583c 100644 --- a/core/src/main/java/io/grpc/internal/GrpcUtil.java +++ b/core/src/main/java/io/grpc/internal/GrpcUtil.java @@ -217,7 +217,7 @@ public byte[] parseAsciiString(byte[] serialized) { public static final Splitter ACCEPT_ENCODING_SPLITTER = Splitter.on(',').trimResults(); - private static final String IMPLEMENTATION_VERSION = "1.51.0"; // CURRENT_GRPC_VERSION + private static final String IMPLEMENTATION_VERSION = "1.51.1"; // CURRENT_GRPC_VERSION /** * The default timeout in nanos for a keepalive ping request. diff --git a/cronet/README.md b/cronet/README.md index b29d19c99b6..01e8d6e9ed7 100644 --- a/cronet/README.md +++ b/cronet/README.md @@ -26,7 +26,7 @@ In your app module's `build.gradle` file, include a dependency on both `grpc-cro Google Play Services Client Library for Cronet ``` -implementation 'io.grpc:grpc-cronet:1.51.0' +implementation 'io.grpc:grpc-cronet:1.51.1' implementation 'com.google.android.gms:play-services-cronet:16.0.0' ``` diff --git a/documentation/android-channel-builder.md b/documentation/android-channel-builder.md index 82bfff47e91..5d4be918962 100644 --- a/documentation/android-channel-builder.md +++ b/documentation/android-channel-builder.md @@ -36,8 +36,8 @@ In your `build.gradle` file, include a dependency on both `grpc-android` and `grpc-okhttp`: ``` -implementation 'io.grpc:grpc-android:1.51.0' -implementation 'io.grpc:grpc-okhttp:1.51.0' +implementation 'io.grpc:grpc-android:1.51.1' +implementation 'io.grpc:grpc-okhttp:1.51.1' ``` You also need permission to access the device's network state in your diff --git a/examples/android/clientcache/app/build.gradle b/examples/android/clientcache/app/build.gradle index f21bda07313..1c9a52f327f 100644 --- a/examples/android/clientcache/app/build.gradle +++ b/examples/android/clientcache/app/build.gradle @@ -34,7 +34,7 @@ android { protobuf { protoc { artifact = 'com.google.protobuf:protoc:3.21.7' } plugins { - grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.51.0' // CURRENT_GRPC_VERSION + grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.51.1' // CURRENT_GRPC_VERSION } } generateProtoTasks { @@ -54,12 +54,12 @@ dependencies { implementation 'com.android.support:appcompat-v7:27.0.2' // You need to build grpc-java to obtain these libraries below. - implementation 'io.grpc:grpc-okhttp:1.51.0' // CURRENT_GRPC_VERSION - implementation 'io.grpc:grpc-protobuf-lite:1.51.0' // CURRENT_GRPC_VERSION - implementation 'io.grpc:grpc-stub:1.51.0' // CURRENT_GRPC_VERSION + implementation 'io.grpc:grpc-okhttp:1.51.1' // CURRENT_GRPC_VERSION + implementation 'io.grpc:grpc-protobuf-lite:1.51.1' // CURRENT_GRPC_VERSION + implementation 'io.grpc:grpc-stub:1.51.1' // CURRENT_GRPC_VERSION implementation 'org.apache.tomcat:annotations-api:6.0.53' testImplementation 'junit:junit:4.12' testImplementation 'com.google.truth:truth:1.0.1' - testImplementation 'io.grpc:grpc-testing:1.51.0' // CURRENT_GRPC_VERSION + testImplementation 'io.grpc:grpc-testing:1.51.1' // CURRENT_GRPC_VERSION } diff --git a/examples/android/helloworld/app/build.gradle b/examples/android/helloworld/app/build.gradle index 1b121c6ab94..70d0b0b8103 100644 --- a/examples/android/helloworld/app/build.gradle +++ b/examples/android/helloworld/app/build.gradle @@ -32,7 +32,7 @@ android { protobuf { protoc { artifact = 'com.google.protobuf:protoc:3.21.7' } plugins { - grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.51.0' // CURRENT_GRPC_VERSION + grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.51.1' // CURRENT_GRPC_VERSION } } generateProtoTasks { @@ -52,8 +52,8 @@ dependencies { implementation 'com.android.support:appcompat-v7:27.0.2' // You need to build grpc-java to obtain these libraries below. - implementation 'io.grpc:grpc-okhttp:1.51.0' // CURRENT_GRPC_VERSION - implementation 'io.grpc:grpc-protobuf-lite:1.51.0' // CURRENT_GRPC_VERSION - implementation 'io.grpc:grpc-stub:1.51.0' // CURRENT_GRPC_VERSION + implementation 'io.grpc:grpc-okhttp:1.51.1' // CURRENT_GRPC_VERSION + implementation 'io.grpc:grpc-protobuf-lite:1.51.1' // CURRENT_GRPC_VERSION + implementation 'io.grpc:grpc-stub:1.51.1' // CURRENT_GRPC_VERSION implementation 'org.apache.tomcat:annotations-api:6.0.53' } diff --git a/examples/android/routeguide/app/build.gradle b/examples/android/routeguide/app/build.gradle index 2529a491f3c..3e939cdddba 100644 --- a/examples/android/routeguide/app/build.gradle +++ b/examples/android/routeguide/app/build.gradle @@ -32,7 +32,7 @@ android { protobuf { protoc { artifact = 'com.google.protobuf:protoc:3.21.7' } plugins { - grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.51.0' // CURRENT_GRPC_VERSION + grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.51.1' // CURRENT_GRPC_VERSION } } generateProtoTasks { @@ -52,8 +52,8 @@ dependencies { implementation 'com.android.support:appcompat-v7:27.0.2' // You need to build grpc-java to obtain these libraries below. - implementation 'io.grpc:grpc-okhttp:1.51.0' // CURRENT_GRPC_VERSION - implementation 'io.grpc:grpc-protobuf-lite:1.51.0' // CURRENT_GRPC_VERSION - implementation 'io.grpc:grpc-stub:1.51.0' // CURRENT_GRPC_VERSION + implementation 'io.grpc:grpc-okhttp:1.51.1' // CURRENT_GRPC_VERSION + implementation 'io.grpc:grpc-protobuf-lite:1.51.1' // CURRENT_GRPC_VERSION + implementation 'io.grpc:grpc-stub:1.51.1' // CURRENT_GRPC_VERSION implementation 'org.apache.tomcat:annotations-api:6.0.53' } diff --git a/examples/android/strictmode/app/build.gradle b/examples/android/strictmode/app/build.gradle index 98d526f3291..c3b98566de2 100644 --- a/examples/android/strictmode/app/build.gradle +++ b/examples/android/strictmode/app/build.gradle @@ -33,7 +33,7 @@ android { protobuf { protoc { artifact = 'com.google.protobuf:protoc:3.21.7' } plugins { - grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.51.0' // CURRENT_GRPC_VERSION + grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.51.1' // CURRENT_GRPC_VERSION } } generateProtoTasks { @@ -53,8 +53,8 @@ dependencies { implementation 'com.android.support:appcompat-v7:28.0.0' // You need to build grpc-java to obtain these libraries below. - implementation 'io.grpc:grpc-okhttp:1.51.0' // CURRENT_GRPC_VERSION - implementation 'io.grpc:grpc-protobuf-lite:1.51.0' // CURRENT_GRPC_VERSION - implementation 'io.grpc:grpc-stub:1.51.0' // CURRENT_GRPC_VERSION + implementation 'io.grpc:grpc-okhttp:1.51.1' // CURRENT_GRPC_VERSION + implementation 'io.grpc:grpc-protobuf-lite:1.51.1' // CURRENT_GRPC_VERSION + implementation 'io.grpc:grpc-stub:1.51.1' // CURRENT_GRPC_VERSION implementation 'org.apache.tomcat:annotations-api:6.0.53' } diff --git a/examples/build.gradle b/examples/build.gradle index 4d7c9e4cf33..12ad54211e3 100644 --- a/examples/build.gradle +++ b/examples/build.gradle @@ -22,7 +22,7 @@ targetCompatibility = 1.8 // Feel free to delete the comment at the next line. It is just for safely // updating the version in our release process. -def grpcVersion = '1.51.0' // CURRENT_GRPC_VERSION +def grpcVersion = '1.51.1' // CURRENT_GRPC_VERSION def protobufVersion = '3.21.7' def protocVersion = protobufVersion diff --git a/examples/example-alts/build.gradle b/examples/example-alts/build.gradle index 1c7dac5ef39..7c3a69767f3 100644 --- a/examples/example-alts/build.gradle +++ b/examples/example-alts/build.gradle @@ -23,7 +23,7 @@ targetCompatibility = 1.8 // Feel free to delete the comment at the next line. It is just for safely // updating the version in our release process. -def grpcVersion = '1.51.0' // CURRENT_GRPC_VERSION +def grpcVersion = '1.51.1' // CURRENT_GRPC_VERSION def protocVersion = '3.21.7' dependencies { diff --git a/examples/example-gauth/build.gradle b/examples/example-gauth/build.gradle index ca3a1417140..d0562104bd7 100644 --- a/examples/example-gauth/build.gradle +++ b/examples/example-gauth/build.gradle @@ -23,7 +23,7 @@ targetCompatibility = 1.8 // Feel free to delete the comment at the next line. It is just for safely // updating the version in our release process. -def grpcVersion = '1.51.0' // CURRENT_GRPC_VERSION +def grpcVersion = '1.51.1' // CURRENT_GRPC_VERSION def protobufVersion = '3.21.7' def protocVersion = protobufVersion diff --git a/examples/example-gauth/pom.xml b/examples/example-gauth/pom.xml index be1bb554627..d864d24a779 100644 --- a/examples/example-gauth/pom.xml +++ b/examples/example-gauth/pom.xml @@ -6,13 +6,13 @@ jar - 1.51.0 + 1.51.1 example-gauth https://github.com/grpc/grpc-java UTF-8 - 1.51.0 + 1.51.1 3.21.7 1.7 diff --git a/examples/example-hostname/build.gradle b/examples/example-hostname/build.gradle index cbcbcdca3f7..3a261e5bed5 100644 --- a/examples/example-hostname/build.gradle +++ b/examples/example-hostname/build.gradle @@ -21,7 +21,7 @@ targetCompatibility = 1.8 // Feel free to delete the comment at the next line. It is just for safely // updating the version in our release process. -def grpcVersion = '1.51.0' // CURRENT_GRPC_VERSION +def grpcVersion = '1.51.1' // CURRENT_GRPC_VERSION def protobufVersion = '3.21.7' dependencies { diff --git a/examples/example-hostname/pom.xml b/examples/example-hostname/pom.xml index ae803c96edb..e0706fe622d 100644 --- a/examples/example-hostname/pom.xml +++ b/examples/example-hostname/pom.xml @@ -6,13 +6,13 @@ jar - 1.51.0 + 1.51.1 example-hostname https://github.com/grpc/grpc-java UTF-8 - 1.51.0 + 1.51.1 3.21.7 1.7 diff --git a/examples/example-jwt-auth/build.gradle b/examples/example-jwt-auth/build.gradle index d90a993698e..b3f7ede23ac 100644 --- a/examples/example-jwt-auth/build.gradle +++ b/examples/example-jwt-auth/build.gradle @@ -22,7 +22,7 @@ targetCompatibility = 1.8 // Feel free to delete the comment at the next line. It is just for safely // updating the version in our release process. -def grpcVersion = '1.51.0' // CURRENT_GRPC_VERSION +def grpcVersion = '1.51.1' // CURRENT_GRPC_VERSION def protobufVersion = '3.21.7' def protocVersion = protobufVersion diff --git a/examples/example-jwt-auth/pom.xml b/examples/example-jwt-auth/pom.xml index dccaf31ea4f..eeb2b150419 100644 --- a/examples/example-jwt-auth/pom.xml +++ b/examples/example-jwt-auth/pom.xml @@ -7,13 +7,13 @@ jar - 1.51.0 + 1.51.1 example-jwt-auth https://github.com/grpc/grpc-java UTF-8 - 1.51.0 + 1.51.1 3.21.7 3.21.7 diff --git a/examples/example-orca/build.gradle b/examples/example-orca/build.gradle index 80eccee6d24..2e1f2f42805 100644 --- a/examples/example-orca/build.gradle +++ b/examples/example-orca/build.gradle @@ -17,7 +17,7 @@ repositories { sourceCompatibility = 1.8 targetCompatibility = 1.8 -def grpcVersion = '1.51.0' // CURRENT_GRPC_VERSION +def grpcVersion = '1.51.1' // CURRENT_GRPC_VERSION def protocVersion = '3.21.7' dependencies { diff --git a/examples/example-tls/build.gradle b/examples/example-tls/build.gradle index df8381481ba..80e2e3779c7 100644 --- a/examples/example-tls/build.gradle +++ b/examples/example-tls/build.gradle @@ -23,7 +23,7 @@ targetCompatibility = 1.8 // Feel free to delete the comment at the next line. It is just for safely // updating the version in our release process. -def grpcVersion = '1.51.0' // CURRENT_GRPC_VERSION +def grpcVersion = '1.51.1' // CURRENT_GRPC_VERSION def protocVersion = '3.21.7' dependencies { diff --git a/examples/example-tls/pom.xml b/examples/example-tls/pom.xml index 60cfb44a9d3..a1e8d6f5398 100644 --- a/examples/example-tls/pom.xml +++ b/examples/example-tls/pom.xml @@ -6,13 +6,13 @@ jar - 1.51.0 + 1.51.1 example-tls https://github.com/grpc/grpc-java UTF-8 - 1.51.0 + 1.51.1 3.21.7 2.0.54.Final diff --git a/examples/example-xds/build.gradle b/examples/example-xds/build.gradle index f9048a91180..e89c4c46f7f 100644 --- a/examples/example-xds/build.gradle +++ b/examples/example-xds/build.gradle @@ -22,7 +22,7 @@ targetCompatibility = 1.8 // Feel free to delete the comment at the next line. It is just for safely // updating the version in our release process. -def grpcVersion = '1.51.0' // CURRENT_GRPC_VERSION +def grpcVersion = '1.51.1' // CURRENT_GRPC_VERSION def nettyTcNativeVersion = '2.0.31.Final' def protocVersion = '3.21.7' diff --git a/examples/pom.xml b/examples/pom.xml index 91f3e174566..89068b754d4 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,13 +6,13 @@ jar - 1.51.0 + 1.51.1 examples https://github.com/grpc/grpc-java UTF-8 - 1.51.0 + 1.51.1 3.21.7 3.21.7 diff --git a/xds/src/main/java/io/grpc/xds/PriorityLoadBalancer.java b/xds/src/main/java/io/grpc/xds/PriorityLoadBalancer.java index 0a9def370e3..3e539f54b06 100644 --- a/xds/src/main/java/io/grpc/xds/PriorityLoadBalancer.java +++ b/xds/src/main/java/io/grpc/xds/PriorityLoadBalancer.java @@ -37,6 +37,8 @@ import io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig.PriorityChildConfig; import io.grpc.xds.XdsLogger.XdsLogLevel; import io.grpc.xds.XdsSubchannelPickers.ErrorPicker; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -59,6 +61,8 @@ final class PriorityLoadBalancer extends LoadBalancer { // Includes all active and deactivated children. Mutable. New entries are only added from priority // 0 up to the selected priority. An entry is only deleted 15 minutes after its deactivation. + // Note that because all configuration updates should be atomic, updates to children can happen + // outside of the synchronization context. Therefore copy values before looping over them. private final Map children = new HashMap<>(); // Following fields are only null initially. @@ -91,15 +95,20 @@ public boolean acceptResolvedAddresses(ResolvedAddresses resolvedAddresses) { priorityNames = config.priorities; priorityConfigs = config.childConfigs; Set prioritySet = new HashSet<>(config.priorities); - for (String priority : children.keySet()) { + ArrayList childKeys = new ArrayList<>(children.keySet()); + for (String priority : childKeys) { if (!prioritySet.contains(priority)) { - children.get(priority).deactivate(); + ChildLbState childLbState = children.get(priority); + if (childLbState != null) { + childLbState.deactivate(); + } } } handlingResolvedAddresses = true; for (String priority : priorityNames) { - if (children.containsKey(priority)) { - children.get(priority).updateResolvedAddresses(); + ChildLbState childLbState = children.get(priority); + if (childLbState != null) { + childLbState.updateResolvedAddresses(); } } handlingResolvedAddresses = false; @@ -111,7 +120,8 @@ public boolean acceptResolvedAddresses(ResolvedAddresses resolvedAddresses) { public void handleNameResolutionError(Status error) { logger.log(XdsLogLevel.WARNING, "Received name resolution error: {0}", error); boolean gotoTransientFailure = true; - for (ChildLbState child : children.values()) { + Collection childValues = new ArrayList<>(children.values()); + for (ChildLbState child : childValues) { if (priorityNames.contains(child.priority)) { child.lb.handleNameResolutionError(error); gotoTransientFailure = false; @@ -125,7 +135,8 @@ public void handleNameResolutionError(Status error) { @Override public void shutdown() { logger.log(XdsLogLevel.INFO, "Shutdown"); - for (ChildLbState child : children.values()) { + Collection childValues = new ArrayList<>(children.values()); + for (ChildLbState child : childValues) { child.tearDown(); } children.clear();