From eba00875164db10f89b71906c889608017f02edc Mon Sep 17 00:00:00 2001 From: Sushan Bhattarai Date: Sun, 1 Mar 2026 17:39:26 -0500 Subject: [PATCH 01/11] fix(bigtable): plumb transport type correctly --- .../csm/tracers/ChannelPoolMetricsTracer.java | 5 +-- .../v2/stub/MetadataExtractorInterceptor.java | 5 +++ .../gaxx/grpc/BigtableChannelObserver.java | 3 +- .../gaxx/grpc/BigtableChannelPool.java | 44 ++++++++++++++----- .../tracers/ChannelPoolMetricsTracerTest.java | 38 ++++++++++------ 5 files changed, 64 insertions(+), 31 deletions(-) diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/csm/tracers/ChannelPoolMetricsTracer.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/csm/tracers/ChannelPoolMetricsTracer.java index 0eb9242b77..ec132e4dad 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/csm/tracers/ChannelPoolMetricsTracer.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/csm/tracers/ChannelPoolMetricsTracer.java @@ -84,10 +84,7 @@ public void run() { LoadBalancingStrategy lbPolicy = lbPolicyRef.get(); for (BigtableChannelObserver info : channelInsights) { - TransportType transportType = - info.isAltsChannel() - ? TransportType.TRANSPORT_TYPE_DIRECT_ACCESS - : TransportType.TRANSPORT_TYPE_CLOUD_PATH; + TransportType transportType = info.getTransportType(); long currentOutstandingUnaryRpcs = info.getOutstandingUnaryRpcs(); long currentOutstandingStreamingRpcs = info.getOutstandingStreamingRpcs(); diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/MetadataExtractorInterceptor.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/MetadataExtractorInterceptor.java index 14ad73131f..39b1525cc6 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/MetadataExtractorInterceptor.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/MetadataExtractorInterceptor.java @@ -88,6 +88,11 @@ public static class SidebandData { private static final CallOptions.Key KEY = CallOptions.Key.create("bigtable-sideband"); + @Nullable + public static SidebandData from(CallOptions callOptions) { + return callOptions == null ? null : callOptions.getOption(KEY); + } + private static final Metadata.Key SERVER_TIMING_HEADER_KEY = Metadata.Key.of("server-timing", Metadata.ASCII_STRING_MARSHALLER); private static final Pattern SERVER_TIMING_HEADER_PATTERN = diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelObserver.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelObserver.java index a718f5fa06..2230e14bf2 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelObserver.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelObserver.java @@ -16,6 +16,7 @@ package com.google.cloud.bigtable.gaxx.grpc; import com.google.api.core.InternalApi; +import com.google.bigtable.v2.PeerInfo; /** Provides observability about a single channel in the channel pool. */ @InternalApi @@ -32,5 +33,5 @@ public interface BigtableChannelObserver { /** Get the current number of successful requests since the last observed period */ long getAndResetSuccessCount(); - boolean isAltsChannel(); + PeerInfo.TransportType getTransportType(); } diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java index f5f1928c2a..d35e853cd8 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java @@ -17,6 +17,8 @@ import com.google.api.core.InternalApi; import com.google.api.gax.grpc.ChannelFactory; +import com.google.bigtable.v2.PeerInfo; +import com.google.cloud.bigtable.data.v2.stub.MetadataExtractorInterceptor; import com.google.cloud.bigtable.gaxx.grpc.ChannelPoolHealthChecker.ProbeResult; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; @@ -543,7 +545,9 @@ static class Entry implements BigtableChannelObserver { * outstanding RPCs has to happen when the ClientCall is closed or the ClientCall failed to * start. */ - @VisibleForTesting final AtomicReference isAltsHolder = new AtomicReference<>(null); + @VisibleForTesting + final AtomicReference transportChannelHolder = + new AtomicReference<>(com.google.bigtable.v2.PeerInfo.TransportType.TRANSPORT_TYPE_UNKNOWN); @VisibleForTesting final AtomicInteger errorCount = new AtomicInteger(0); @VisibleForTesting final AtomicInteger successCount = new AtomicInteger(0); @@ -576,10 +580,22 @@ static class Entry implements BigtableChannelObserver { this.channel = channel; } - void checkAndSetIsAlts(ClientCall call) { - // TODO(populate ALTS holder) - boolean result = false; - isAltsHolder.compareAndSet(null, result); + void checkAndSetTransportType(Status status, CallOptions callOptions) { + // set to UNKNOWN if error + if (!status.isOk()) { + transportChannelHolder.set( + com.google.bigtable.v2.PeerInfo.TransportType.TRANSPORT_TYPE_UNKNOWN); + return; + } + MetadataExtractorInterceptor.SidebandData sidebandData = + MetadataExtractorInterceptor.SidebandData.from(callOptions); + + if (sidebandData != null) { + com.google.bigtable.v2.PeerInfo peerInfo = sidebandData.getPeerInfo(); + if (peerInfo != null) { + transportChannelHolder.set(peerInfo.getTransportType()); + } + } } ManagedChannel getManagedChannel() { @@ -683,9 +699,8 @@ public long getAndResetSuccessCount() { } @Override - public boolean isAltsChannel() { - Boolean val = isAltsHolder.get(); - return val != null && val; + public PeerInfo.TransportType getTransportType() { + return transportChannelHolder.get(); } void incrementErrorCount() { @@ -717,7 +732,7 @@ public ClientCall newCall( methodDescriptor.getType() == MethodDescriptor.MethodType.SERVER_STREAMING; Entry entry = getRetainedEntry(index, isStreaming); return new ReleasingClientCall<>( - entry.channel.newCall(methodDescriptor, callOptions), entry, isStreaming); + entry.channel.newCall(methodDescriptor, callOptions), entry, isStreaming, callOptions); } } @@ -726,13 +741,19 @@ static class ReleasingClientCall extends SimpleForwardingClientCall @Nullable private CancellationException cancellationException; final Entry entry; private final boolean isStreaming; + private final CallOptions callOptions; private final AtomicBoolean wasClosed = new AtomicBoolean(); private final AtomicBoolean wasReleased = new AtomicBoolean(); - public ReleasingClientCall(ClientCall delegate, Entry entry, boolean isStreaming) { + public ReleasingClientCall( + ClientCall delegate, + Entry entry, + boolean isStreaming, + CallOptions callOptions) { super(delegate); this.entry = entry; this.isStreaming = isStreaming; + this.callOptions = callOptions; } @Override @@ -741,12 +762,11 @@ public void start(Listener responseListener, Metadata headers) { throw new IllegalStateException("Call is already cancelled", cancellationException); } try { - entry.checkAndSetIsAlts(delegate()); - super.start( new SimpleForwardingClientCallListener(responseListener) { @Override public void onClose(Status status, Metadata trailers) { + entry.checkAndSetTransportType(status, callOptions); if (!wasClosed.compareAndSet(false, true)) { LOG.log( Level.WARNING, diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/csm/tracers/ChannelPoolMetricsTracerTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/csm/tracers/ChannelPoolMetricsTracerTest.java index fec4f7956a..fca44b08de 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/csm/tracers/ChannelPoolMetricsTracerTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/csm/tracers/ChannelPoolMetricsTracerTest.java @@ -20,6 +20,7 @@ import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.when; +import com.google.bigtable.v2.PeerInfo; import com.google.cloud.bigtable.data.v2.internal.api.InstanceName; import com.google.cloud.bigtable.data.v2.internal.csm.MetricRegistry; import com.google.cloud.bigtable.data.v2.internal.csm.attributes.ClientInfo; @@ -56,6 +57,9 @@ @RunWith(JUnit4.class) public class ChannelPoolMetricsTracerTest { + private static final String PROJECT_ID = "fake-project"; + private static final String INSTANCE_ID = "fake-instance"; + private static final String APP_PROFILE_ID = "fake-profile"; @Rule public final MockitoRule mockito = MockitoJUnit.rule(); @@ -74,8 +78,8 @@ public void setUp() { metricReader = InMemoryMetricReader.create(); ClientInfo clientInfo = ClientInfo.builder() - .setInstanceName(InstanceName.of("fake-project", "fake-instance")) - .setAppProfileId("fake-profile") + .setInstanceName(InstanceName.of(PROJECT_ID, INSTANCE_ID)) + .setAppProfileId(APP_PROFILE_ID) .build(); SdkMeterProvider meterProvider = SdkMeterProvider.builder().registerMetricReader(metricReader).build(); @@ -105,8 +109,10 @@ public void setUp() { when(mockInsight2.getOutstandingStreamingRpcs()).thenReturn(0); when(mockInsight2.getAndResetErrorCount()).thenReturn(0L); when(mockInsight2.getAndResetSuccessCount()).thenReturn(0L); - when(mockInsight1.isAltsChannel()).thenReturn(false); - when(mockInsight2.isAltsChannel()).thenReturn(false); + when(mockInsight1.getTransportType()) + .thenReturn(PeerInfo.TransportType.TRANSPORT_TYPE_CLOUD_PATH); + when(mockInsight2.getTransportType()) + .thenReturn(PeerInfo.TransportType.TRANSPORT_TYPE_CLOUD_PATH); } /** Helper to run the captured ChannelPoolMetricsTracer task. */ @@ -119,11 +125,24 @@ void runTrackerTask() { } private Attributes getExpectedErrorAttributes() { - return Attributes.builder().build(); + return Attributes.builder() + .put(AttributeKey.stringKey("project_id"), PROJECT_ID) + .put(AttributeKey.stringKey("instance"), INSTANCE_ID) + .put(AttributeKey.stringKey("app_profile"), APP_PROFILE_ID) + .put( + AttributeKey.stringKey("client_name"), + "java-bigtable/" + com.google.cloud.bigtable.Version.VERSION) + .build(); } private static Attributes getExpectedRpcAttributes(String lbPolicy, boolean streaming) { return Attributes.builder() + .put(AttributeKey.stringKey("project_id"), PROJECT_ID) + .put(AttributeKey.stringKey("instance"), INSTANCE_ID) + .put(AttributeKey.stringKey("app_profile"), APP_PROFILE_ID) + .put( + AttributeKey.stringKey("client_name"), + "java-bigtable/" + com.google.cloud.bigtable.Version.VERSION) .put(AttributeKey.stringKey("transport_type"), "cloudpath") .put(AttributeKey.stringKey("lb_policy"), lbPolicy) .put(AttributeKey.booleanKey("streaming"), streaming) @@ -147,15 +166,6 @@ private static HistogramPointData getPointForStreaming( () -> new AssertionError("Missing HistogramPointData for streaming=" + streaming)); } - /** Helper to create expected Attributes for assertions. */ - private static Attributes getExpectedAttributes(String lbPolicy, boolean streaming) { - return Attributes.builder() - .put(AttributeKey.stringKey("transport_type"), "grpc") - .put(AttributeKey.stringKey("lb_policy"), lbPolicy) - .put(AttributeKey.booleanKey("streaming"), streaming) - .build(); - } - @Test public void testSingleRun() { // Arrange From a2ae74ac0633d1f61e4938f3d13cc27f3f4032d1 Mon Sep 17 00:00:00 2001 From: Sushan Bhattarai Date: Mon, 2 Mar 2026 10:16:46 -0500 Subject: [PATCH 02/11] fix --- .../gaxx/grpc/BigtableChannelPool.java | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java index d35e853cd8..99e51d9998 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java @@ -546,7 +546,7 @@ static class Entry implements BigtableChannelObserver { * start. */ @VisibleForTesting - final AtomicReference transportChannelHolder = + final AtomicReference transportTypeHolder = new AtomicReference<>(com.google.bigtable.v2.PeerInfo.TransportType.TRANSPORT_TYPE_UNKNOWN); @VisibleForTesting final AtomicInteger errorCount = new AtomicInteger(0); @@ -580,21 +580,18 @@ static class Entry implements BigtableChannelObserver { this.channel = channel; } - void checkAndSetTransportType(Status status, CallOptions callOptions) { - // set to UNKNOWN if error - if (!status.isOk()) { - transportChannelHolder.set( - com.google.bigtable.v2.PeerInfo.TransportType.TRANSPORT_TYPE_UNKNOWN); - return; - } + void checkAndSetTransportType(CallOptions callOptions) { MetadataExtractorInterceptor.SidebandData sidebandData = MetadataExtractorInterceptor.SidebandData.from(callOptions); - if (sidebandData != null) { - com.google.bigtable.v2.PeerInfo peerInfo = sidebandData.getPeerInfo(); - if (peerInfo != null) { - transportChannelHolder.set(peerInfo.getTransportType()); - } + // Set to the specific transport type if present, otherwise default to UNKNOWN + // we could check the Status and set it to unknown, but we might have PeerInfo with some non + // OK Status + if (sidebandData != null && sidebandData.getPeerInfo() != null) { + transportTypeHolder.set(sidebandData.getPeerInfo().getTransportType()); + } else { + transportTypeHolder.set( + com.google.bigtable.v2.PeerInfo.TransportType.TRANSPORT_TYPE_UNKNOWN); } } @@ -766,7 +763,7 @@ public void start(Listener responseListener, Metadata headers) { new SimpleForwardingClientCallListener(responseListener) { @Override public void onClose(Status status, Metadata trailers) { - entry.checkAndSetTransportType(status, callOptions); + entry.checkAndSetTransportType(callOptions); if (!wasClosed.compareAndSet(false, true)) { LOG.log( Level.WARNING, From bdfe9515a8c8730943215976ae86532fde69de65 Mon Sep 17 00:00:00 2001 From: Sushan Bhattarai Date: Mon, 2 Mar 2026 10:24:16 -0500 Subject: [PATCH 03/11] fix --- .../google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java index 99e51d9998..eb1bca4c47 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java @@ -697,7 +697,7 @@ public long getAndResetSuccessCount() { @Override public PeerInfo.TransportType getTransportType() { - return transportChannelHolder.get(); + return transportTypeHolder.get(); } void incrementErrorCount() { From 9350ace9845490d945d029c94b52e0cc3822788f Mon Sep 17 00:00:00 2001 From: Sushan Bhattarai Date: Mon, 2 Mar 2026 14:40:50 -0500 Subject: [PATCH 04/11] fix --- .../gaxx/grpc/BigtableChannelPool.java | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java index eb1bca4c47..08cb7099c1 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java @@ -36,6 +36,7 @@ import java.time.Clock; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.Random; import java.util.concurrent.CancellationException; import java.util.concurrent.ConcurrentLinkedQueue; @@ -50,6 +51,8 @@ import java.util.logging.Logger; import javax.annotation.Nullable; +import static com.google.bigtable.v2.PeerInfo.TransportType.TRANSPORT_TYPE_UNKNOWN; + /** * A {@link ManagedChannel} that will send requests round-robin via a set of channels. * @@ -545,9 +548,11 @@ static class Entry implements BigtableChannelObserver { * outstanding RPCs has to happen when the ClientCall is closed or the ClientCall failed to * start. */ + + /** this contains the PeerInfo field of the most recent rpc on this channel entry. */ @VisibleForTesting - final AtomicReference transportTypeHolder = - new AtomicReference<>(com.google.bigtable.v2.PeerInfo.TransportType.TRANSPORT_TYPE_UNKNOWN); + volatile PeerInfo.TransportType transportType = + TRANSPORT_TYPE_UNKNOWN; @VisibleForTesting final AtomicInteger errorCount = new AtomicInteger(0); @VisibleForTesting final AtomicInteger successCount = new AtomicInteger(0); @@ -580,19 +585,17 @@ static class Entry implements BigtableChannelObserver { this.channel = channel; } - void checkAndSetTransportType(CallOptions callOptions) { + void setTransportType(CallOptions callOptions) { MetadataExtractorInterceptor.SidebandData sidebandData = MetadataExtractorInterceptor.SidebandData.from(callOptions); // Set to the specific transport type if present, otherwise default to UNKNOWN // we could check the Status and set it to unknown, but we might have PeerInfo with some non // OK Status - if (sidebandData != null && sidebandData.getPeerInfo() != null) { - transportTypeHolder.set(sidebandData.getPeerInfo().getTransportType()); - } else { - transportTypeHolder.set( - com.google.bigtable.v2.PeerInfo.TransportType.TRANSPORT_TYPE_UNKNOWN); - } + transportType = Optional.ofNullable(sidebandData) + .map(MetadataExtractorInterceptor.SidebandData::getPeerInfo) + .map(PeerInfo::getTransportType) + .orElse(TRANSPORT_TYPE_UNKNOWN); } ManagedChannel getManagedChannel() { @@ -697,7 +700,7 @@ public long getAndResetSuccessCount() { @Override public PeerInfo.TransportType getTransportType() { - return transportTypeHolder.get(); + return transportType; } void incrementErrorCount() { @@ -761,9 +764,13 @@ public void start(Listener responseListener, Metadata headers) { try { super.start( new SimpleForwardingClientCallListener(responseListener) { + @Override + public void onHeaders(Metadata headers) { + entry.setTransportType(callOptions); + super.onHeaders(headers); + } @Override public void onClose(Status status, Metadata trailers) { - entry.checkAndSetTransportType(callOptions); if (!wasClosed.compareAndSet(false, true)) { LOG.log( Level.WARNING, From e10e1eb44a2e8df4b4729a4314f6d7768fc4e75e Mon Sep 17 00:00:00 2001 From: Sushan Bhattarai Date: Mon, 2 Mar 2026 14:42:52 -0500 Subject: [PATCH 05/11] fix --- .../cloud/bigtable/gaxx/grpc/BigtableChannelPool.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java index 08cb7099c1..e83cfaa7df 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java @@ -548,12 +548,6 @@ static class Entry implements BigtableChannelObserver { * outstanding RPCs has to happen when the ClientCall is closed or the ClientCall failed to * start. */ - - /** this contains the PeerInfo field of the most recent rpc on this channel entry. */ - @VisibleForTesting - volatile PeerInfo.TransportType transportType = - TRANSPORT_TYPE_UNKNOWN; - @VisibleForTesting final AtomicInteger errorCount = new AtomicInteger(0); @VisibleForTesting final AtomicInteger successCount = new AtomicInteger(0); @VisibleForTesting final AtomicInteger outstandingUnaryRpcs = new AtomicInteger(0); @@ -563,6 +557,11 @@ static class Entry implements BigtableChannelObserver { private final AtomicInteger maxOutstandingUnaryRpcs = new AtomicInteger(); private final AtomicInteger maxOutstandingStreamingRpcs = new AtomicInteger(); + /** this contains the PeerInfo field of the most recent rpc on this channel entry. */ + @VisibleForTesting + volatile PeerInfo.TransportType transportType = + TRANSPORT_TYPE_UNKNOWN; + /** Queue storing the last 5 minutes of probe results */ @VisibleForTesting final ConcurrentLinkedQueue probeHistory = new ConcurrentLinkedQueue<>(); From 91548d83eb49ad8f192f80488525743925835da1 Mon Sep 17 00:00:00 2001 From: Sushan Bhattarai Date: Mon, 2 Mar 2026 14:46:18 -0500 Subject: [PATCH 06/11] fix --- .../cloud/bigtable/gaxx/grpc/BigtableChannelPool.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java index e83cfaa7df..8decfc0216 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java @@ -51,8 +51,6 @@ import java.util.logging.Logger; import javax.annotation.Nullable; -import static com.google.bigtable.v2.PeerInfo.TransportType.TRANSPORT_TYPE_UNKNOWN; - /** * A {@link ManagedChannel} that will send requests round-robin via a set of channels. * @@ -560,8 +558,8 @@ static class Entry implements BigtableChannelObserver { /** this contains the PeerInfo field of the most recent rpc on this channel entry. */ @VisibleForTesting volatile PeerInfo.TransportType transportType = - TRANSPORT_TYPE_UNKNOWN; - + PeerInfo.TransportType.TRANSPORT_TYPE_UNKNOWN; + /** Queue storing the last 5 minutes of probe results */ @VisibleForTesting final ConcurrentLinkedQueue probeHistory = new ConcurrentLinkedQueue<>(); @@ -594,7 +592,7 @@ void setTransportType(CallOptions callOptions) { transportType = Optional.ofNullable(sidebandData) .map(MetadataExtractorInterceptor.SidebandData::getPeerInfo) .map(PeerInfo::getTransportType) - .orElse(TRANSPORT_TYPE_UNKNOWN); + .orElse(PeerInfo.TransportType.TRANSPORT_TYPE_UNKNOWN); } ManagedChannel getManagedChannel() { From 0fcfdeec2ddc0db86ba262649dd83774198bea2b Mon Sep 17 00:00:00 2001 From: cloud-java-bot Date: Mon, 2 Mar 2026 19:49:13 +0000 Subject: [PATCH 07/11] chore: generate libraries at Mon Mar 2 19:46:43 UTC 2026 --- .../cloud/bigtable/gaxx/grpc/BigtableChannelPool.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java index 8decfc0216..66abb64cab 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java @@ -547,6 +547,7 @@ static class Entry implements BigtableChannelObserver { * start. */ @VisibleForTesting final AtomicInteger errorCount = new AtomicInteger(0); + @VisibleForTesting final AtomicInteger successCount = new AtomicInteger(0); @VisibleForTesting final AtomicInteger outstandingUnaryRpcs = new AtomicInteger(0); @@ -557,8 +558,7 @@ static class Entry implements BigtableChannelObserver { /** this contains the PeerInfo field of the most recent rpc on this channel entry. */ @VisibleForTesting - volatile PeerInfo.TransportType transportType = - PeerInfo.TransportType.TRANSPORT_TYPE_UNKNOWN; + volatile PeerInfo.TransportType transportType = PeerInfo.TransportType.TRANSPORT_TYPE_UNKNOWN; /** Queue storing the last 5 minutes of probe results */ @VisibleForTesting @@ -589,7 +589,8 @@ void setTransportType(CallOptions callOptions) { // Set to the specific transport type if present, otherwise default to UNKNOWN // we could check the Status and set it to unknown, but we might have PeerInfo with some non // OK Status - transportType = Optional.ofNullable(sidebandData) + transportType = + Optional.ofNullable(sidebandData) .map(MetadataExtractorInterceptor.SidebandData::getPeerInfo) .map(PeerInfo::getTransportType) .orElse(PeerInfo.TransportType.TRANSPORT_TYPE_UNKNOWN); @@ -766,6 +767,7 @@ public void onHeaders(Metadata headers) { entry.setTransportType(callOptions); super.onHeaders(headers); } + @Override public void onClose(Status status, Metadata trailers) { if (!wasClosed.compareAndSet(false, true)) { From 4131361a2048243e3b14901161f07b59452b8e64 Mon Sep 17 00:00:00 2001 From: Sushan Bhattarai Date: Mon, 2 Mar 2026 14:56:49 -0500 Subject: [PATCH 08/11] fix --- .../bigtable/data/v2/stub/MetadataExtractorInterceptor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/MetadataExtractorInterceptor.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/MetadataExtractorInterceptor.java index 39b1525cc6..7d21a5f498 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/MetadataExtractorInterceptor.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/MetadataExtractorInterceptor.java @@ -90,7 +90,7 @@ public static class SidebandData { @Nullable public static SidebandData from(CallOptions callOptions) { - return callOptions == null ? null : callOptions.getOption(KEY); + return callOptions.getOption(KEY); } private static final Metadata.Key SERVER_TIMING_HEADER_KEY = From dac01ee14e18ea6cadda197752659f279a3f3145 Mon Sep 17 00:00:00 2001 From: Sushan Bhattarai Date: Tue, 3 Mar 2026 15:27:58 -0500 Subject: [PATCH 09/11] log --- .../data/v2/stub/MetadataExtractorInterceptor.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/MetadataExtractorInterceptor.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/MetadataExtractorInterceptor.java index 7d21a5f498..5627765d6c 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/MetadataExtractorInterceptor.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/MetadataExtractorInterceptor.java @@ -35,12 +35,15 @@ import io.grpc.alts.AltsContextUtil; import java.time.Duration; import java.util.Base64; +import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.Nullable; @InternalApi public class MetadataExtractorInterceptor implements ClientInterceptor { + static final Logger LOG = Logger.getLogger(MetadataExtractorInterceptor.class.getName()); + private final SidebandData sidebandData = new SidebandData(); public GrpcCallContext injectInto(GrpcCallContext ctx) { @@ -128,9 +131,14 @@ private void reset() { } void onResponseHeaders(Metadata md, Attributes attributes) { + LOG.info("Raw Response Metadata: " + md); + peerInfo = extractPeerInfo(md, gfeTiming, attributes); + // 3. Log the final resolved PeerInfo responseParams = extractResponseParams(md); gfeTiming = extractGfeLatency(md); + LOG.info("Extracted GFE Timing (server-timing): " + gfeTiming); peerInfo = extractPeerInfo(md, gfeTiming, attributes); + LOG.info("Final Resolved PeerInfo: " + peerInfo); } void onClose(Status status, Metadata trailers) { @@ -157,7 +165,9 @@ private static Duration extractGfeLatency(Metadata metadata) { private static PeerInfo extractPeerInfo( Metadata metadata, Duration gfeTiming, Attributes attributes) { String encodedStr = metadata.get(PEER_INFO_KEY); + LOG.info("Raw bigtable-peer-info header value: " + encodedStr); if (Strings.isNullOrEmpty(encodedStr)) { + LOG.info("bigtable-peer-info header was missing or empty. Returning null."); return null; } @@ -165,14 +175,18 @@ private static PeerInfo extractPeerInfo( byte[] decoded = Base64.getUrlDecoder().decode(encodedStr); PeerInfo peerInfo = PeerInfo.parseFrom(decoded); PeerInfo.TransportType effectiveTransport = peerInfo.getTransportType(); + LOG.info("Parsed TransportType straight from protobuf: " + effectiveTransport); // TODO: remove this once transport_type is being sent by the server // This is a temporary workaround to detect directpath until its available from the server if (effectiveTransport == PeerInfo.TransportType.TRANSPORT_TYPE_UNKNOWN) { + LOG.info("TransportType was UNKNOWN. Fallback checking ALTS context: isAlts=" + isAlts); boolean isAlts = AltsContextUtil.check(attributes); if (isAlts) { + LOG.info("Fallback applied: Set to DIRECT_ACCESS based on ALTS."); effectiveTransport = PeerInfo.TransportType.TRANSPORT_TYPE_DIRECT_ACCESS; } else if (gfeTiming != null) { + LOG.info("Fallback applied: Set to CLOUD_PATH based on presence of gfeTiming."); effectiveTransport = PeerInfo.TransportType.TRANSPORT_TYPE_CLOUD_PATH; } } From 310b0a24e0baaa71a6469412c35c81d53cdad348 Mon Sep 17 00:00:00 2001 From: Sushan Bhattarai Date: Tue, 3 Mar 2026 15:32:08 -0500 Subject: [PATCH 10/11] fix --- .../bigtable/data/v2/stub/MetadataExtractorInterceptor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/MetadataExtractorInterceptor.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/MetadataExtractorInterceptor.java index 5627765d6c..4912ddcc36 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/MetadataExtractorInterceptor.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/MetadataExtractorInterceptor.java @@ -180,8 +180,8 @@ private static PeerInfo extractPeerInfo( // TODO: remove this once transport_type is being sent by the server // This is a temporary workaround to detect directpath until its available from the server if (effectiveTransport == PeerInfo.TransportType.TRANSPORT_TYPE_UNKNOWN) { - LOG.info("TransportType was UNKNOWN. Fallback checking ALTS context: isAlts=" + isAlts); boolean isAlts = AltsContextUtil.check(attributes); + LOG.info("TransportType was UNKNOWN. Fallback checking ALTS context: isAlts=" + isAlts); if (isAlts) { LOG.info("Fallback applied: Set to DIRECT_ACCESS based on ALTS."); effectiveTransport = PeerInfo.TransportType.TRANSPORT_TYPE_DIRECT_ACCESS; From 50b2aec1deea0088ddf5ccb4095c3b6cf118a99a Mon Sep 17 00:00:00 2001 From: Sushan Bhattarai Date: Tue, 3 Mar 2026 15:58:18 -0500 Subject: [PATCH 11/11] fix --- .../google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java index 66abb64cab..6bbfba1398 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java @@ -764,8 +764,8 @@ public void start(Listener responseListener, Metadata headers) { new SimpleForwardingClientCallListener(responseListener) { @Override public void onHeaders(Metadata headers) { - entry.setTransportType(callOptions); super.onHeaders(headers); + entry.setTransportType(callOptions); } @Override