Skip to content

Commit c50f1fc

Browse files
feat: populate client_stats in AppendRowsRequest
1 parent 6bb477b commit c50f1fc

2 files changed

Lines changed: 75 additions & 0 deletions

File tree

‎java-bigquerystorage/google-cloud-bigquerystorage/src/main/java/com/google/cloud/bigquery/storage/v1/ConnectionWorker.java‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,6 +1289,11 @@ private void appendLoop() {
12891289
}
12901290
firstRequestForTableOrSchemaSwitch = false;
12911291

1292+
ClientStats clientStats = createClientStats(wrapper);
1293+
if (!clientStats.equals(ClientStats.getDefaultInstance())) {
1294+
originalRequestBuilder.setClientStats(clientStats);
1295+
}
1296+
12921297
requestProfilerHook.startOperation(
12931298
RequestProfiler.OperationName.RESPONSE_LATENCY, requestUniqueId);
12941299

@@ -1307,6 +1312,20 @@ private void appendLoop() {
13071312
cleanupConnectionAndRequests(/* avoidBlocking= */ false);
13081313
}
13091314

1315+
private ClientStats createClientStats(AppendRequestAndResponse requestWrapper) {
1316+
ClientStats.Builder clientStatsBuilder = ClientStats.newBuilder();
1317+
ClientStats.RequestStats.Builder requestStatsBuilder = ClientStats.RequestStats.newBuilder();
1318+
boolean requestStatsModified = false;
1319+
if (requestWrapper.requestSendTimeStamp != null) {
1320+
requestStatsBuilder.setSendTimeMillis(requestWrapper.requestSendTimeStamp.toEpochMilli());
1321+
requestStatsModified = true;
1322+
}
1323+
if (requestStatsModified) {
1324+
clientStatsBuilder.setRequestStats(requestStatsBuilder.build());
1325+
}
1326+
return clientStatsBuilder.build();
1327+
}
1328+
13101329
@Nullable
13111330
private AppendRowsSchema getSchema(AppendRowsRequest request) {
13121331
if (request.hasProtoRows()) {

‎java-bigquerystorage/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/ConnectionWorkerTest.java‎

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.google.cloud.bigquery.storage.test.Test.FooType;
3333
import com.google.cloud.bigquery.storage.test.Test.InnerType;
3434
import com.google.cloud.bigquery.storage.v1.ConnectionWorker.Load;
35+
import com.google.common.collect.Iterables;
3536
import com.google.protobuf.ByteString;
3637
import com.google.protobuf.DescriptorProtos;
3738
import com.google.protobuf.Int64Value;
@@ -1722,6 +1723,61 @@ void testEarliestSendTime_retryScenario() throws Exception {
17221723

17231724
// Once exhausted, state should be null
17241725
assertThat(connectionWorker.getEarliestSendTime()).isNull();
1726+
1727+
AppendRowsRequest initialRequest = testBigQueryWrite.getAppendRequests().get(0);
1728+
AppendRowsRequest retryRequest = testBigQueryWrite.getAppendRequests().get(1);
1729+
assertThat(retryRequest.getClientStats().getRequestStats().getSendTimeMillis())
1730+
.isAtLeast(initialRequest.getClientStats().getRequestStats().getSendTimeMillis());
1731+
}
1732+
}
1733+
1734+
@Test
1735+
void testClientStats_sendTimeMillisPopulated() throws Exception {
1736+
// Arrange
1737+
ProtoSchema schema1 = createProtoSchema("foo");
1738+
try (StreamWriter sw1 =
1739+
StreamWriter.newBuilder(TEST_STREAM_1, client)
1740+
.setLocation("us")
1741+
.setWriterSchema(schema1)
1742+
.build();
1743+
ConnectionWorker connectionWorker = createConnectionWorker()) {
1744+
testBigQueryWrite.addResponse(createAppendResponse(0));
1745+
1746+
// Act
1747+
long beforeSendMillis = Instant.now().toEpochMilli();
1748+
ApiFuture<AppendRowsResponse> future =
1749+
sendTestMessage(connectionWorker, sw1, createFooProtoRows(new String[] {"0"}), 0);
1750+
future.get();
1751+
long afterSendMillis = Instant.now().toEpochMilli();
1752+
1753+
// Assert
1754+
AppendRowsRequest sentRequest =
1755+
Iterables.getOnlyElement(testBigQueryWrite.getAppendRequests());
1756+
assertThat(sentRequest.hasClientStats()).isTrue();
1757+
assertThat(sentRequest.getClientStats().hasRequestStats()).isTrue();
1758+
assertThat(sentRequest.getClientStats().getRequestStats().hasSendTimeMillis()).isTrue();
1759+
long sendTimeMillis = sentRequest.getClientStats().getRequestStats().getSendTimeMillis();
1760+
assertThat(sendTimeMillis).isAtLeast(beforeSendMillis);
1761+
assertThat(sendTimeMillis).isAtMost(afterSendMillis);
1762+
1763+
// Arrange retry scenario
1764+
testBigQueryWrite.addResponse(
1765+
new DummyResponseSupplierWillFailThenSucceed(
1766+
new FakeBigQueryWriteImpl.Response(createAppendResponse(1)),
1767+
/* totalFailCount= */ 1,
1768+
com.google.rpc.Status.newBuilder().setCode(Code.INTERNAL.ordinal()).build()));
1769+
1770+
// Act
1771+
ApiFuture<AppendRowsResponse> retryFuture =
1772+
sendTestMessage(connectionWorker, sw1, createFooProtoRows(new String[] {"1"}), 1);
1773+
retryFuture.get();
1774+
1775+
// Assert
1776+
assertThat(testBigQueryWrite.getAppendRequests()).hasSize(3);
1777+
AppendRowsRequest initialRequest = testBigQueryWrite.getAppendRequests().get(1);
1778+
AppendRowsRequest retryRequest = testBigQueryWrite.getAppendRequests().get(2);
1779+
assertThat(retryRequest.getClientStats().getRequestStats().getSendTimeMillis())
1780+
.isAtLeast(initialRequest.getClientStats().getRequestStats().getSendTimeMillis());
17251781
}
17261782
}
17271783
}

0 commit comments

Comments
 (0)