Skip to content

Commit

Permalink
fix: Conformance test sample rowkeys generic deadline (#1562)
Browse files Browse the repository at this point in the history
* clean up server deprecated code

* test passes now with changes to test proxy

* remove passing test

* remove await

* fix sync repo settings

* grab app profileId from client

* remove passing test

* changes to timeout

* fix deadline error

* remove package.json line

* fix prettier issues

* remove old functions for deadline

* Update bulk-mutate-rows.js

* Update read-rows.js

* Update read-modify-write-row.js

* Update read-row.js

* Update sampleRowKeys.ts
  • Loading branch information
kevkim-codes authored Jan 7, 2025
1 parent 4bb14d6 commit 2fdf98f
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 27 deletions.
17 changes: 16 additions & 1 deletion src/tabular-api-surface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -902,8 +902,23 @@ Please use the format 'prezzy' or '${instance.name}/tables/prezzy'.`);
typeof optionsOrCallback === 'function' ? optionsOrCallback : cb!;
const gaxOptions =
typeof optionsOrCallback === 'object' ? optionsOrCallback : {};

/*
The following line of code sets the timeout if it was provided while
creating the client. This will be used to determine if the client should
retry on DEADLINE_EXCEEDED errors. Eventually, this will be handled
downstream in google-gax.
*/
const timeout = gaxOptions?.timeout;
const callTimeMillis = new Date().getTime();

this.sampleRowKeysStream(gaxOptions)
.on('error', callback)
.on('error', (error: grpc.ServiceError) => {
if (timeout && timeout > new Date().getTime() - callTimeMillis) {
error.code = grpc.status.DEADLINE_EXCEEDED;
}
callback(error);
})
.pipe(
concat((keys: string[]) => {
callback(null, keys);
Expand Down
1 change: 0 additions & 1 deletion testproxy/known_failures.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,5 @@ TestReadRows_Retry_WithRoutingCookie\|
TestReadRows_Retry_WithRoutingCookie_MultipleErrorResponses\|
TestReadRows_Retry_WithRetryInfo\|
TestReadRows_Retry_WithRetryInfo_MultipleErrorResponse\|
TestSampleRowKeys_Generic_DeadlineExceeded\|
TestSampleRowKeys_Retry_WithRoutingCookie\|
TestSampleRowKeys_Generic_CloseClient
46 changes: 21 additions & 25 deletions testproxy/services/sample-row-keys.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,34 @@
'use strict';

const grpc = require('@grpc/grpc-js');

const {
getSRKRequest,
} = require('../../build/testproxy/services/utils/request/sampleRowKeys.js');
const normalizeCallback = require('./utils/normalize-callback.js');

const v2 = Symbol.for('v2');

const sampleRowKeys = ({clientMap}) =>
normalizeCallback(async rawRequest => {
const {request} = rawRequest;
const {request: sampleRowKeysRequest} = request;
const {tableName} = sampleRowKeysRequest;
const {clientId} = request;
const {clientId, request: sampleRowKeysRequest} = request;
const {appProfileId, tableName} = sampleRowKeysRequest;

const bigtable = clientMap.get(clientId);
bigtable.appProfileId = appProfileId;

try {
const response = await getSRKRequest(bigtable, {appProfileId, tableName});

const appProfileId = clientMap.get(clientId).appProfileId;
const client = clientMap.get(clientId)[v2];
const samples = await new Promise((res, rej) => {
const response = [];
client
.sampleRowKeys({
appProfileId,
tableName,
})
.on('data', data => {
response.push(data);
})
.on('error', rej)
.on('end', () => res(response));
});
return {
status: {code: grpc.status.OK, details: []},
response,
};
} catch (error) {
console.error('Error:', error.code);

return {
status: {code: grpc.status.OK, details: []},
samples,
};
return {
status: {code: error.code, details: []},
};
}
});

module.exports = sampleRowKeys;
48 changes: 48 additions & 0 deletions testproxy/services/utils/request/sampleRowKeys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import * as protos from '../../../../protos/protos';

type SRKRequest = protos.google.bigtable.v2.ISampleRowKeysRequest;
type SRKResponse = protos.google.bigtable.v2.ISampleRowKeysResponse;

/**
* This function will create a request that can be passed into the
* handwritten ßsampleRowKeys method and calls the Gapic layer under the hood.
*
* @param {any} client Bigtable client
* @param {SRKRequest} request The sampleRowKeys request information
* that can be sent to the Gapic layer.
* @returns {Promise<SRKResponse>} A reponse that can be passed into the
* sampleRowKeys Gapic layer.
*/
export function getSRKRequest(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
client: any,
request: SRKRequest
): Promise<SRKResponse> {
const {tableName} = request;

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const getTableInfo = (bigtable: any, tableName: any) => {
const [, , , instanceId, , tableId] = tableName.split('/');
const instance = bigtable.instance(instanceId);
return instance.table(tableId);
};

const table = getTableInfo(client, tableName);
const sampleRowKeysResponse = table.sampleRowKeys();

return sampleRowKeysResponse;
}

0 comments on commit 2fdf98f

Please sign in to comment.