Skip to content
This repository was archived by the owner on May 8, 2026. It is now read-only.

Commit 98fe29b

Browse files
committed
fix: feedback
Change-Id: Ib7f24524b6050ec11ca18e5dc624ca8513f99ec8
1 parent c77e876 commit 98fe29b

4 files changed

Lines changed: 36 additions & 29 deletions

File tree

google-cloud-bigtable/clirr-ignored-differences.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,4 +419,11 @@
419419
<method>*create*</method>
420420
<to>*</to>
421421
</difference>
422+
<!-- change method return type is ok because BigtableChannelPrimer is InternalApi -->
423+
<difference>
424+
<differenceType>7006</differenceType>
425+
<className>com/google/cloud/bigtable/data/v2/stub/BigtableChannelPrimer</className>
426+
<method>*sendPrimeRequestsAsync*</method>
427+
<to>com.google.api.core.ApiFuture</to>
428+
</difference>
422429
</differences>

google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,11 @@ public class BigtableChannelPool extends ManagedChannel {
6464
private final BigtableChannelPoolSettings settings;
6565
private final ChannelFactory channelFactory;
6666

67-
private ChannelPrimer channelPrimer;
67+
private final ChannelPrimer channelPrimer;
6868
private final ScheduledExecutorService executor;
6969
private final Object entryWriteLock = new Object();
7070
@VisibleForTesting final AtomicReference<ImmutableList<Entry>> entries = new AtomicReference<>();
71-
private ChannelPoolHealthChecker channelPoolHealthChecker;
71+
private final ChannelPoolHealthChecker channelPoolHealthChecker;
7272
private final AtomicInteger indexTicker = new AtomicInteger();
7373
private final String authority;
7474

google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/ChannelPoolHealthChecker.java

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.google.cloud.bigtable.data.v2.stub.BigtableChannelPrimer;
2222
import com.google.cloud.bigtable.gaxx.grpc.BigtableChannelPool.Entry;
2323
import com.google.common.annotations.VisibleForTesting;
24+
import com.google.common.base.Preconditions;
2425
import com.google.common.collect.ImmutableList;
2526
import com.google.common.util.concurrent.MoreExecutors;
2627
import java.time.Clock;
@@ -98,7 +99,9 @@ public ChannelPoolHealthChecker(
9899
}
99100

100101
void start() {
101-
if (channelPrimer instanceof BigtableChannelPrimer) {
102+
if (!(channelPrimer instanceof BigtableChannelPrimer)) {
103+
logger.log(Level.WARNING, "Provided channelPrimer not an instance of BigtableChannelPrimer, not checking channel health.");
104+
} else {
102105
Duration initialDelayProbe =
103106
Duration.ofMillis(ThreadLocalRandom.current().nextLong(PROBE_INTERVAL.toMillis()));
104107
this.probeTaskScheduledFuture =
@@ -115,34 +118,30 @@ void start() {
115118
initialDelayDetect.toMillis(),
116119
PROBE_INTERVAL.toMillis(),
117120
TimeUnit.MILLISECONDS);
118-
} else {
119-
logger.log(Level.WARNING, "NoOpChannelPrimer was provided, not checking channel health.");
120121
}
121122
}
122123

123124
/** Stop running health checking */
124125
public void stop() {
125126
if (probeTaskScheduledFuture != null) {
126-
probeTaskScheduledFuture.cancel(true);
127+
probeTaskScheduledFuture.cancel(false);
127128
}
128129
if (detectAndRemoveTaskScheduledFuture != null) {
129-
detectAndRemoveTaskScheduledFuture.cancel(true);
130+
detectAndRemoveTaskScheduledFuture.cancel(false);
130131
}
131132
}
132133

133134
/** Runs probes on all the channels in the pool. */
134135
@VisibleForTesting
135136
void runProbes() {
137+
Preconditions.checkState(channelPrimer instanceof BigtableChannelPrimer, "Health checking can only be enabled with BigtableChannelPrimer, found %s", channelPrimer);
136138
for (Entry entry : this.entrySupplier.get()) {
137139
final Instant startTime = clock.instant();
138140
final ApiFuture<PingAndWarmResponse> probeFuture;
139141

140-
if (channelPrimer instanceof BigtableChannelPrimer) {
141-
BigtableChannelPrimer primer = (BigtableChannelPrimer) channelPrimer;
142-
probeFuture = primer.sendPrimeRequestsAsync(entry.getManagedChannel());
143-
} else {
144-
continue;
145-
}
142+
BigtableChannelPrimer primer = (BigtableChannelPrimer) channelPrimer;
143+
probeFuture = primer.sendPrimeRequestsAsync(entry.getManagedChannel());
144+
146145
probeFuture.addListener(
147146
() -> onComplete(entry, startTime, probeFuture), MoreExecutors.directExecutor());
148147
}

google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientFactoryTest.java

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import com.google.common.base.Preconditions;
4141
import com.google.common.io.BaseEncoding;
4242
import io.grpc.Attributes;
43+
import io.grpc.Grpc;
4344
import io.grpc.Metadata;
4445
import io.grpc.Server;
4546
import io.grpc.ServerCall;
@@ -50,9 +51,12 @@
5051
import io.grpc.stub.StreamObserver;
5152
import java.io.IOException;
5253
import java.lang.reflect.Method;
54+
import java.net.SocketAddress;
5355
import java.util.LinkedList;
5456
import java.util.List;
5557
import java.util.concurrent.BlockingQueue;
58+
import java.util.concurrent.ConcurrentHashMap;
59+
import java.util.concurrent.ConcurrentMap;
5660
import java.util.concurrent.LinkedBlockingDeque;
5761
import org.junit.After;
5862
import org.junit.Before;
@@ -87,6 +91,7 @@ public class BigtableDataClientFactoryTest {
8791
private final BlockingQueue<Attributes> setUpAttributes = new LinkedBlockingDeque<>();
8892
private final BlockingQueue<Attributes> terminateAttributes = new LinkedBlockingDeque<>();
8993
private final BlockingQueue<Metadata> requestMetadata = new LinkedBlockingDeque<>();
94+
private final ConcurrentMap<SocketAddress, Boolean> warmedChannels = new ConcurrentHashMap<>();
9095

9196
@Before
9297
public void setUp() throws IOException {
@@ -101,6 +106,15 @@ public <ReqT, RespT> Listener<ReqT> interceptCall(
101106
Metadata headers,
102107
ServerCallHandler<ReqT, RespT> next) {
103108
requestMetadata.add(headers);
109+
110+
// Check if the call is PingAndWarm and mark the channel address as warmed up.
111+
if (BigtableGrpc.getPingAndWarmMethod().equals(call.getMethodDescriptor())) {
112+
SocketAddress remoteAddr =
113+
call.getAttributes().get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR);
114+
if (remoteAddr != null) {
115+
warmedChannels.put(remoteAddr, true);
116+
}
117+
}
104118
return next.startCall(call, headers);
105119
}
106120
})
@@ -249,7 +263,7 @@ public void testCreateForInstanceWithAppProfileHasCorrectSettings() throws Excep
249263
@Test
250264
public void testCreateWithRefreshingChannel() throws Exception {
251265
int poolSize = 3;
252-
BigtableDataSettings.Builder builder =
266+
BigtableDataSettings.Builder builder =
253267
BigtableDataSettings.newBuilderForEmulator(server.getPort())
254268
.setProjectId(DEFAULT_PROJECT_ID)
255269
.setInstanceId(DEFAULT_INSTANCE_ID)
@@ -278,21 +292,8 @@ public void testCreateWithRefreshingChannel() throws Exception {
278292
Mockito.verify(executorProvider, Mockito.times(1)).getExecutor();
279293
Mockito.verify(watchdogProvider, Mockito.times(1)).getWatchdog();
280294

281-
// Make sure that the clients are sharing the same ChannelPool
282-
assertThat(setUpAttributes).hasSize(poolSize);
283-
284-
// Make sure that prime requests were sent only once per table per connection
285-
assertThat(service.pingAndWarmRequests).hasSize(poolSize);
286-
List<PingAndWarmRequest> expectedRequests = new LinkedList<>();
287-
for (int i = 0; i < poolSize; i++) {
288-
expectedRequests.add(
289-
PingAndWarmRequest.newBuilder()
290-
.setName(InstanceName.format(DEFAULT_PROJECT_ID, DEFAULT_INSTANCE_ID))
291-
.setAppProfileId(DEFAULT_APP_PROFILE_ID)
292-
.build());
293-
}
294-
295-
assertThat(service.pingAndWarmRequests).containsExactly(expectedRequests.toArray());
295+
assertThat(warmedChannels).hasSize(poolSize);
296+
assertThat(warmedChannels.values()).doesNotContain(false);
296297

297298
// Wait for all the connections to close asynchronously
298299
factory.close();

0 commit comments

Comments
 (0)