在此先感謝您的幫助。
我正在嘗試在 Spanner nodejs 客戶端中設定每次呼叫超時。我已經通讀了給定的 Spanner 檔案,其中最好的在這里:https://cloud.google.com/spanner/docs/custom-timeout-and-retry。本檔案忽略了您需要提供gaxOptions. 或者我誤解了,鑒于我無法解釋我所看到的行為,這并不奇怪。
我在這里創建了一個小型 repo 來存放這個復制品:https : //github.com/brg8/spanner-nodejs-timeout-repro。代碼也粘貼在下面。
const PROJECT_ID_HERE = "";
const SPANNER_INSTANCE_ID_HERE = "";
const SPANNER_DATABASE_HERE = "";
const TABLE_NAME_HERE = "";
const { Spanner } = require("@google-cloud/spanner");
let client = null;
client = new Spanner({
projectId: PROJECT_ID_HERE,
});
const instance = client.instance(SPANNER_INSTANCE_ID_HERE);
const database = instance.database(SPANNER_DATABASE_HERE);
async function runQuery(additionalOptions = {}) {
const t1 = new Date();
try {
console.log("Launching query...");
await database.run({
sql: `SELECT * FROM ${TABLE_NAME_HERE} LIMIT 1000;`,
...additionalOptions,
});
console.log("Everything finished.");
} catch (err) {
console.log(err);
console.log("Timed out after", new Date() - t1);
}
};
// Query finishes, no timeout (as expected)
runQuery();
/*
Launching query...
Everything finished.
*/
// Query times out (as expected)
// However, it only times out after 7-8 seconds
runQuery({
gaxOptions: {
timeout: 1,
},
});
/*
Launching query...
Error: 4 DEADLINE_EXCEEDED: Deadline exceeded
at Object.callErrorFromStatus (/Users/benjamingodlove/Developer/spanner-node-repro/node_modules/@grpc/grpc-js/build/src/call.js:31:26)
at Object.onReceiveStatus (/Users/benjamingodlove/Developer/spanner-node-repro/node_modules/@grpc/grpc-js/build/src/client.js:330:49)
at /Users/benjamingodlove/Developer/spanner-node-repro/node_modules/@grpc/grpc-js/build/src/call-stream.js:80:35
at Object.onReceiveStatus (/Users/benjamingodlove/Developer/spanner-node-repro/node_modules/grpc-gcp/build/src/index.js:73:29)
at InterceptingListenerImpl.onReceiveStatus (/Users/benjamingodlove/Developer/spanner-node-repro/node_modules/@grpc/grpc-js/build/src/call-stream.js:75:23)
at Object.onReceiveStatus (/Users/benjamingodlove/Developer/spanner-node-repro/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:299:181)
at /Users/benjamingodlove/Developer/spanner-node-repro/node_modules/@grpc/grpc-js/build/src/call-stream.js:145:78
at processTicksAndRejections (node:internal/process/task_queues:76:11) {
code: 4,
details: 'Deadline exceeded',
metadata: Metadata { internalRepr: Map(0) {}, options: {} }
}
Timed out after 7238
*/
還有我的 package.json
{
"name": "spanner-node-repro",
"version": "1.0.0",
"description": "Reproducing timeout wonkiness with Spanner.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@google-cloud/spanner": "^5.15.2"
}
}
任何見解表示贊賞!
- 本·戈德洛夫
uj5u.com熱心網友回復:
TLDR
添加retryRequestOptions: {noResponseRetries: 0},到您的,gaxOptions以便您獲得以下選項:
const query = {
sql: 'SELECT ...',
gaxOptions: {
timeout: 1,
retryRequestOptions: {noResponseRetries: 0},
},
};
更長的版本
幕后發生的事情如下:
- 發送(流)查詢請求并且超時發生在服務器回傳任何回應之前。
- 默認的重試設定包括一個
noResponseRetries: 2選項,這意味著如果客戶端根本沒有收到任何回應,請求將重試兩次。 - 請求的重試只會在隨機重試延遲后開始。每次重試嘗試都會增加此延遲。
- 重試兩次后(因此在總共發送 3 個請求之后),DEADLINE_EXCEEDED 錯誤將傳播到客戶端。這些重試大約需要 7 秒,因為第一次重試等待大約 2.5 秒,第二次等待 4.5 秒(這兩個值都包含 1 秒的隨機抖動值,因此實際值將始終在 6 到 8 秒之間)
設定noResponseRetries: 0禁用未收到服務器回應的請求的重試。
您還將看到,如果您將超時設定為更“合理”的值,您將看到查詢以正常方式超時,因為服務器有機會回應。將其設定為 1500(意味著 1500 毫秒,即 1.5 秒)會導致超時使用您的示例代碼按預期作業。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/315651.html
