@proteinjs/db-driver-spanner 1.12.3 → 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/LICENSE +21 -0
- package/dist/generated/index.js +1 -1
- package/dist/generated/index.js.map +1 -1
- package/dist/generated/test/index.d.ts.map +1 -1
- package/dist/generated/test/index.js +3 -1
- package/dist/generated/test/index.js.map +1 -1
- package/dist/src/SpannerConfig.d.ts +22 -0
- package/dist/src/SpannerConfig.d.ts.map +1 -1
- package/dist/src/SpannerDriver.d.ts +56 -9
- package/dist/src/SpannerDriver.d.ts.map +1 -1
- package/dist/src/SpannerDriver.js +229 -35
- package/dist/src/SpannerDriver.js.map +1 -1
- package/dist/src/SpannerLivenessMonitor.d.ts +25 -0
- package/dist/src/SpannerLivenessMonitor.d.ts.map +1 -1
- package/dist/src/SpannerLivenessMonitor.js +59 -4
- package/dist/src/SpannerLivenessMonitor.js.map +1 -1
- package/dist/test/ServiceUpdateVerbs.test.d.ts +2 -0
- package/dist/test/ServiceUpdateVerbs.test.d.ts.map +1 -0
- package/dist/test/ServiceUpdateVerbs.test.js +325 -0
- package/dist/test/ServiceUpdateVerbs.test.js.map +1 -0
- package/dist/test/SessionPoolExhaustion.test.d.ts +2 -0
- package/dist/test/SessionPoolExhaustion.test.d.ts.map +1 -0
- package/dist/test/SessionPoolExhaustion.test.js +230 -0
- package/dist/test/SessionPoolExhaustion.test.js.map +1 -0
- package/dist/test/SessionRecordTableQuery.test.d.ts +2 -0
- package/dist/test/SessionRecordTableQuery.test.d.ts.map +1 -0
- package/dist/test/SessionRecordTableQuery.test.js +185 -0
- package/dist/test/SessionRecordTableQuery.test.js.map +1 -0
- package/dist/test/SpannerLivenessMonitor.test.js +65 -0
- package/dist/test/SpannerLivenessMonitor.test.js.map +1 -1
- package/dist/test/SpannerOperationDeadline.test.d.ts +2 -0
- package/dist/test/SpannerOperationDeadline.test.d.ts.map +1 -0
- package/dist/test/SpannerOperationDeadline.test.js +227 -0
- package/dist/test/SpannerOperationDeadline.test.js.map +1 -0
- package/dist/test/TransactionSafety.test.d.ts +2 -0
- package/dist/test/TransactionSafety.test.d.ts.map +1 -0
- package/dist/test/TransactionSafety.test.js +325 -0
- package/dist/test/TransactionSafety.test.js.map +1 -0
- package/dist/test/index.d.ts +1 -0
- package/dist/test/index.d.ts.map +1 -1
- package/dist/test/index.js +1 -0
- package/dist/test/index.js.map +1 -1
- package/dist/test/util/serviceUpdateVerbsTestTables.d.ts +45 -0
- package/dist/test/util/serviceUpdateVerbsTestTables.d.ts.map +1 -0
- package/dist/test/util/serviceUpdateVerbsTestTables.js +100 -0
- package/dist/test/util/serviceUpdateVerbsTestTables.js.map +1 -0
- package/generated/index.ts +6 -9
- package/generated/test/index.ts +9 -10
- package/package.json +7 -6
- package/src/SpannerConfig.ts +22 -0
- package/src/SpannerDriver.ts +215 -28
- package/src/SpannerLivenessMonitor.ts +73 -5
- package/test/ServiceUpdateVerbs.test.ts +188 -0
- package/test/SessionPoolExhaustion.test.ts +127 -0
- package/test/SessionRecordTableQuery.test.ts +118 -0
- package/test/SpannerLivenessMonitor.test.ts +70 -0
- package/test/SpannerOperationDeadline.test.ts +156 -0
- package/test/TransactionSafety.test.ts +157 -0
- package/test/index.ts +1 -0
- package/test/util/serviceUpdateVerbsTestTables.ts +55 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
|
3
|
+
var extendStatics = function (d, b) {
|
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
+
return extendStatics(d, b);
|
|
8
|
+
};
|
|
9
|
+
return function (d, b) {
|
|
10
|
+
if (typeof b !== "function" && b !== null)
|
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
+
extendStatics(d, b);
|
|
13
|
+
function __() { this.constructor = d; }
|
|
14
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
+
};
|
|
16
|
+
})();
|
|
17
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
18
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
19
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
20
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
21
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
22
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
23
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
27
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
28
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
29
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
30
|
+
function step(op) {
|
|
31
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
32
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
33
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
34
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
35
|
+
switch (op[0]) {
|
|
36
|
+
case 0: case 1: t = op; break;
|
|
37
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
38
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
39
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
40
|
+
default:
|
|
41
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
42
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
43
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
44
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
45
|
+
if (t[2]) _.ops.pop();
|
|
46
|
+
_.trys.pop(); continue;
|
|
47
|
+
}
|
|
48
|
+
op = body.call(thisArg, _);
|
|
49
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
50
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
54
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
55
|
+
};
|
|
56
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
57
|
+
var moment_1 = __importDefault(require("moment"));
|
|
58
|
+
var db_driver_spanner_1 = require("@proteinjs/db-driver-spanner");
|
|
59
|
+
var db_1 = require("@proteinjs/db");
|
|
60
|
+
var db_transaction_context_1 = require("@proteinjs/db-transaction-context");
|
|
61
|
+
var getDropTestTable_1 = require("./util/getDropTestTable");
|
|
62
|
+
var SpannerEmulatorProvisioner_1 = require("./util/SpannerEmulatorProvisioner");
|
|
63
|
+
require("../generated/test/index");
|
|
64
|
+
/** Mirrors @proteinjs/user SessionTable column-for-column (namespaced test table name). */
|
|
65
|
+
var SessionShapeTable = /** @class */ (function (_super) {
|
|
66
|
+
__extends(SessionShapeTable, _super);
|
|
67
|
+
function SessionShapeTable() {
|
|
68
|
+
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
69
|
+
_this.name = 'db_test_session_record_table_query';
|
|
70
|
+
_this.columns = (0, db_1.withRecordColumns)({
|
|
71
|
+
sessionId: new db_1.StringColumn('session_id'),
|
|
72
|
+
session: new db_1.StringColumn('serialized_session', {}, 4000),
|
|
73
|
+
expires: new db_1.DateColumn('expires'),
|
|
74
|
+
userEmail: new db_1.StringColumn('user_email'),
|
|
75
|
+
});
|
|
76
|
+
return _this;
|
|
77
|
+
}
|
|
78
|
+
return SessionShapeTable;
|
|
79
|
+
}(db_1.Table));
|
|
80
|
+
var table = new SessionShapeTable();
|
|
81
|
+
var getTable = function (tableName) {
|
|
82
|
+
if (tableName === table.name) {
|
|
83
|
+
return table;
|
|
84
|
+
}
|
|
85
|
+
throw new Error("Unexpected table lookup in test: ".concat(tableName));
|
|
86
|
+
};
|
|
87
|
+
var spannerDriver = new db_driver_spanner_1.SpannerDriver({
|
|
88
|
+
projectId: 'proteinjs-test',
|
|
89
|
+
instanceName: 'proteinjs-test',
|
|
90
|
+
databaseName: 'test',
|
|
91
|
+
}, getTable);
|
|
92
|
+
/**
|
|
93
|
+
* What DbSessionStore serializes into a row (shape from a real dev session). `updated` is
|
|
94
|
+
* stamped explicitly for deterministic newest-first assertions: the insert-time default takes
|
|
95
|
+
* moment() per row, and rows landing in the same millisecond would make the order ambiguous.
|
|
96
|
+
*/
|
|
97
|
+
var storeShapedRow = function (n, updatedMs) { return ({
|
|
98
|
+
sessionId: "test-session-".concat(n),
|
|
99
|
+
session: JSON.stringify({
|
|
100
|
+
cookie: { originalMaxAge: 5184000000, expires: '2026-10-01T00:00:00.000Z', httpOnly: true, path: '/' },
|
|
101
|
+
passport: { user: "user-".concat(n, "@test.local") },
|
|
102
|
+
}),
|
|
103
|
+
expires: new Date(Date.now() + 5184000000),
|
|
104
|
+
userEmail: "user-".concat(n, "@test.local"),
|
|
105
|
+
updated: (0, moment_1.default)(updatedMs),
|
|
106
|
+
}); };
|
|
107
|
+
describe('Session-shaped record table query (the admin Sessions table path)', function () {
|
|
108
|
+
var dropTable = (0, getDropTestTable_1.getDropTestTable)(spannerDriver);
|
|
109
|
+
// Writes as the session store writes (system db), reads as the record table reads.
|
|
110
|
+
var systemDb = new db_1.Db(spannerDriver, getTable, new db_transaction_context_1.TransactionContext(), true);
|
|
111
|
+
var db = new db_1.Db(spannerDriver, getTable, new db_transaction_context_1.TransactionContext());
|
|
112
|
+
beforeAll(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
113
|
+
return __generator(this, function (_a) {
|
|
114
|
+
switch (_a.label) {
|
|
115
|
+
case 0: return [4 /*yield*/, SpannerEmulatorProvisioner_1.SpannerEmulatorProvisioner.ensureProvisioned({
|
|
116
|
+
projectId: 'proteinjs-test',
|
|
117
|
+
instanceName: 'proteinjs-test',
|
|
118
|
+
databaseName: 'test',
|
|
119
|
+
})];
|
|
120
|
+
case 1:
|
|
121
|
+
_a.sent();
|
|
122
|
+
return [4 /*yield*/, dropTable(table)];
|
|
123
|
+
case 2:
|
|
124
|
+
_a.sent();
|
|
125
|
+
return [4 /*yield*/, spannerDriver.getTableManager().loadTable(table)];
|
|
126
|
+
case 3:
|
|
127
|
+
_a.sent();
|
|
128
|
+
return [2 /*return*/];
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}); }, 60000);
|
|
132
|
+
afterAll(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
133
|
+
return __generator(this, function (_a) {
|
|
134
|
+
switch (_a.label) {
|
|
135
|
+
case 0: return [4 /*yield*/, dropTable(table)];
|
|
136
|
+
case 1:
|
|
137
|
+
_a.sent();
|
|
138
|
+
return [4 /*yield*/, SpannerEmulatorProvisioner_1.SpannerEmulatorProvisioner.release()];
|
|
139
|
+
case 2:
|
|
140
|
+
_a.sent();
|
|
141
|
+
return [2 /*return*/];
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}); }, 30000);
|
|
145
|
+
test('store-written session rows all come back through the record-table query, newest-first', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
146
|
+
var base, n, qb, rows, countQb, _a;
|
|
147
|
+
return __generator(this, function (_b) {
|
|
148
|
+
switch (_b.label) {
|
|
149
|
+
case 0:
|
|
150
|
+
base = Date.now() - 60000;
|
|
151
|
+
n = 1;
|
|
152
|
+
_b.label = 1;
|
|
153
|
+
case 1:
|
|
154
|
+
if (!(n <= 3)) return [3 /*break*/, 4];
|
|
155
|
+
return [4 /*yield*/, systemDb.insert(table, storeShapedRow(n, base + n * 1000))];
|
|
156
|
+
case 2:
|
|
157
|
+
_b.sent();
|
|
158
|
+
_b.label = 3;
|
|
159
|
+
case 3:
|
|
160
|
+
n++;
|
|
161
|
+
return [3 /*break*/, 1];
|
|
162
|
+
case 4:
|
|
163
|
+
qb = new db_1.QueryBuilderFactory()
|
|
164
|
+
.createQueryBuilder(table)
|
|
165
|
+
.sort([{ field: 'updated', desc: true }])
|
|
166
|
+
.paginate({ start: 0, end: 10 });
|
|
167
|
+
return [4 /*yield*/, db.query(table, qb)];
|
|
168
|
+
case 5:
|
|
169
|
+
rows = _b.sent();
|
|
170
|
+
expect(rows.map(function (row) { return row.sessionId; })).toEqual(['test-session-3', 'test-session-2', 'test-session-1']);
|
|
171
|
+
// Round-trip fidelity of the store-shaped fields the table displays.
|
|
172
|
+
expect(rows[0].userEmail).toBe('user-3@test.local');
|
|
173
|
+
expect(JSON.parse(rows[0].session).passport.user).toBe('user-3@test.local');
|
|
174
|
+
expect(rows[0].expires).toBeTruthy();
|
|
175
|
+
countQb = new db_1.QueryBuilderFactory().createQueryBuilder(table);
|
|
176
|
+
_a = expect;
|
|
177
|
+
return [4 /*yield*/, db.getRowCount(table, countQb)];
|
|
178
|
+
case 6:
|
|
179
|
+
_a.apply(void 0, [_b.sent()]).toBe(3);
|
|
180
|
+
return [2 /*return*/];
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}); }, 60000);
|
|
184
|
+
});
|
|
185
|
+
//# sourceMappingURL=SessionRecordTableQuery.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SessionRecordTableQuery.test.js","sourceRoot":"","sources":["../../test/SessionRecordTableQuery.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -122,6 +122,29 @@ describe('SpannerLivenessMonitor', function () {
|
|
|
122
122
|
}
|
|
123
123
|
});
|
|
124
124
|
}); });
|
|
125
|
+
test('the sustained-failure exit is RESTART-REQUESTED (code 86) so supervision respawns instead of staying down', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
126
|
+
var processExitSpy, check;
|
|
127
|
+
return __generator(this, function (_a) {
|
|
128
|
+
switch (_a.label) {
|
|
129
|
+
case 0:
|
|
130
|
+
// The serve-package contract (ServePackageSupervisor.RESTART_REQUEST_EXIT_CODE): 86 asks
|
|
131
|
+
// the supervisor for a respawn with backoff; a plain exit(1) is mirrored and stays down —
|
|
132
|
+
// observed as a dev server dead all night after a transient network outage.
|
|
133
|
+
exitSpy.mockRestore();
|
|
134
|
+
processExitSpy = jest.spyOn(process, 'exit').mockImplementation((function () { return undefined; }));
|
|
135
|
+
probeSpy.mockRejectedValue(new Error('14 UNAVAILABLE: fake'));
|
|
136
|
+
check = internals.verifyLiveness();
|
|
137
|
+
return [4 /*yield*/, jest.advanceTimersByTimeAsync(ALL_PROBE_DELAYS_MS)];
|
|
138
|
+
case 1:
|
|
139
|
+
_a.sent();
|
|
140
|
+
return [4 /*yield*/, check];
|
|
141
|
+
case 2:
|
|
142
|
+
_a.sent();
|
|
143
|
+
expect(processExitSpy).toHaveBeenCalledWith(86);
|
|
144
|
+
return [2 /*return*/];
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}); });
|
|
125
148
|
test('burst coalescing: reportError while a check is in flight triggers one probe cycle', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
126
149
|
return __generator(this, function (_a) {
|
|
127
150
|
switch (_a.label) {
|
|
@@ -155,4 +178,46 @@ describe('SpannerLivenessMonitor', function () {
|
|
|
155
178
|
});
|
|
156
179
|
}); });
|
|
157
180
|
});
|
|
181
|
+
describe('SpannerLivenessMonitor pool gauge (P4a)', function () {
|
|
182
|
+
var fakePool = { size: 25, available: 20, borrowed: 5, totalWaiters: 0 };
|
|
183
|
+
var monitor;
|
|
184
|
+
var warnLogSpy;
|
|
185
|
+
beforeEach(function () {
|
|
186
|
+
fakePool.size = 25;
|
|
187
|
+
fakePool.available = 20;
|
|
188
|
+
fakePool.borrowed = 5;
|
|
189
|
+
fakePool.totalWaiters = 0;
|
|
190
|
+
monitor = new db_driver_spanner_1.SpannerLivenessMonitor({ pool_: fakePool });
|
|
191
|
+
warnLogSpy = jest.spyOn(monitor.logger, 'warn').mockImplementation(function () { });
|
|
192
|
+
});
|
|
193
|
+
afterEach(function () {
|
|
194
|
+
jest.restoreAllMocks();
|
|
195
|
+
});
|
|
196
|
+
test('poolStats surfaces the four pool numbers', function () {
|
|
197
|
+
expect(monitor.poolStats()).toEqual({ size: 25, available: 20, borrowed: 5, totalWaiters: 0 });
|
|
198
|
+
});
|
|
199
|
+
test('no waiters: no pressure warning', function () {
|
|
200
|
+
monitor.logPoolPressure(1000);
|
|
201
|
+
expect(warnLogSpy).not.toHaveBeenCalled();
|
|
202
|
+
});
|
|
203
|
+
test('waiters > 0: warns with the four pool numbers', function () {
|
|
204
|
+
fakePool.available = 0;
|
|
205
|
+
fakePool.borrowed = 25;
|
|
206
|
+
fakePool.totalWaiters = 3;
|
|
207
|
+
monitor.logPoolPressure(1000);
|
|
208
|
+
expect(warnLogSpy).toHaveBeenCalledTimes(1);
|
|
209
|
+
expect(warnLogSpy).toHaveBeenCalledWith(expect.objectContaining({
|
|
210
|
+
message: expect.stringContaining('session pool under pressure'),
|
|
211
|
+
obj: { size: 25, available: 0, borrowed: 25, totalWaiters: 3 },
|
|
212
|
+
}));
|
|
213
|
+
});
|
|
214
|
+
test('pressure warnings are throttled to one per interval', function () {
|
|
215
|
+
fakePool.totalWaiters = 3;
|
|
216
|
+
monitor.logPoolPressure(1000);
|
|
217
|
+
monitor.logPoolPressure(2000); // within the 10s interval — suppressed
|
|
218
|
+
expect(warnLogSpy).toHaveBeenCalledTimes(1);
|
|
219
|
+
monitor.logPoolPressure(11000); // interval elapsed — warns again
|
|
220
|
+
expect(warnLogSpy).toHaveBeenCalledTimes(2);
|
|
221
|
+
});
|
|
222
|
+
});
|
|
158
223
|
//# sourceMappingURL=SpannerLivenessMonitor.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpannerLivenessMonitor.test.js","sourceRoot":"","sources":["../../test/SpannerLivenessMonitor.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SpannerLivenessMonitor.test.js","sourceRoot":"","sources":["../../test/SpannerLivenessMonitor.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpannerOperationDeadline.test.d.ts","sourceRoot":"","sources":["../../test/SpannerOperationDeadline.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
16
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
17
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
18
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
19
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
24
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
|
+
function step(op) {
|
|
27
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
28
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
29
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
30
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
31
|
+
switch (op[0]) {
|
|
32
|
+
case 0: case 1: t = op; break;
|
|
33
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
34
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
+
default:
|
|
37
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
+
if (t[2]) _.ops.pop();
|
|
42
|
+
_.trys.pop(); continue;
|
|
43
|
+
}
|
|
44
|
+
op = body.call(thisArg, _);
|
|
45
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
var db_driver_spanner_1 = require("@proteinjs/db-driver-spanner");
|
|
51
|
+
var statics = db_driver_spanner_1.SpannerDriver;
|
|
52
|
+
var fakeMonitor = {
|
|
53
|
+
logPoolPressure: function () { return undefined; },
|
|
54
|
+
poolStats: function () { return ({ size: 0, available: 0, borrowed: 0, totalWaiters: 0 }); },
|
|
55
|
+
reportError: function () { return undefined; },
|
|
56
|
+
stop: function () { return undefined; },
|
|
57
|
+
};
|
|
58
|
+
var hang = function () { return new Promise(function () { return undefined; }); };
|
|
59
|
+
var generateStatement = (function () { return ({ sql: 'UPDATE t SET x = 1', namedParams: { params: {} } }); });
|
|
60
|
+
var waitFor = function (condition, timeoutMs, label) { return __awaiter(void 0, void 0, void 0, function () {
|
|
61
|
+
var deadline;
|
|
62
|
+
return __generator(this, function (_a) {
|
|
63
|
+
switch (_a.label) {
|
|
64
|
+
case 0:
|
|
65
|
+
deadline = Date.now() + timeoutMs;
|
|
66
|
+
_a.label = 1;
|
|
67
|
+
case 1:
|
|
68
|
+
if (!(Date.now() < deadline)) return [3 /*break*/, 3];
|
|
69
|
+
if (condition()) {
|
|
70
|
+
return [2 /*return*/];
|
|
71
|
+
}
|
|
72
|
+
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 25); })];
|
|
73
|
+
case 2:
|
|
74
|
+
_a.sent();
|
|
75
|
+
return [3 /*break*/, 1];
|
|
76
|
+
case 3: throw new Error("Timed out waiting for: ".concat(label));
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}); };
|
|
80
|
+
var makeDriver = function (config, db) {
|
|
81
|
+
statics.SPANNER_DB = db;
|
|
82
|
+
statics.LIVENESS_MONITOR = fakeMonitor;
|
|
83
|
+
var driver = new db_driver_spanner_1.SpannerDriver(__assign({ projectId: 'fake', instanceName: 'fake', databaseName: 'fake' }, config));
|
|
84
|
+
// deadline/error logs are expected output of these tests — keep the run quiet
|
|
85
|
+
jest.spyOn(driver.logger, 'error').mockImplementation(function () { return undefined; });
|
|
86
|
+
jest.spyOn(driver.logger, 'warn').mockImplementation(function () { return undefined; });
|
|
87
|
+
return driver;
|
|
88
|
+
};
|
|
89
|
+
describe('Spanner op deadlines', function () {
|
|
90
|
+
beforeEach(function () {
|
|
91
|
+
statics.CLIENT_GENERATION = 0;
|
|
92
|
+
statics.CONSECUTIVE_DEADLINE_FAILURES = 0;
|
|
93
|
+
});
|
|
94
|
+
afterEach(function () {
|
|
95
|
+
statics.SPANNER = undefined;
|
|
96
|
+
statics.SPANNER_INSTANCE = undefined;
|
|
97
|
+
statics.SPANNER_DB = undefined;
|
|
98
|
+
statics.LIVENESS_MONITOR = undefined;
|
|
99
|
+
statics.CONSECUTIVE_DEADLINE_FAILURES = 0;
|
|
100
|
+
jest.restoreAllMocks();
|
|
101
|
+
});
|
|
102
|
+
test('a hanging query op fails at the deadline with an error naming it, carrying the same gRPC deadline', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
103
|
+
var run, driver;
|
|
104
|
+
return __generator(this, function (_a) {
|
|
105
|
+
switch (_a.label) {
|
|
106
|
+
case 0:
|
|
107
|
+
run = jest.fn(function (_request) { return hang(); });
|
|
108
|
+
driver = makeDriver({ operationDeadlineMs: 150, deadlineFailuresBeforeRecycle: 99 }, { run: run });
|
|
109
|
+
return [4 /*yield*/, expect(driver.runQuery(generateStatement)).rejects.toThrow(/150ms deadline.*spanner query/)];
|
|
110
|
+
case 1:
|
|
111
|
+
_a.sent();
|
|
112
|
+
// The gRPC deadline on the request is the lever that cancels the RPC on a dead channel —
|
|
113
|
+
// the library's stream error path is what returns the borrowed session to the pool.
|
|
114
|
+
expect(run.mock.calls[0][0]).toMatchObject({ gaxOptions: { timeout: 150 } });
|
|
115
|
+
return [2 /*return*/];
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}); }, 5000);
|
|
119
|
+
test('a dml transaction hung on a dead channel (dml AND rollback hang) still RETURNS its session', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
120
|
+
var released, transaction, db, driver;
|
|
121
|
+
return __generator(this, function (_a) {
|
|
122
|
+
switch (_a.label) {
|
|
123
|
+
case 0:
|
|
124
|
+
released = [];
|
|
125
|
+
transaction = {
|
|
126
|
+
runUpdate: jest.fn(function () { return hang(); }),
|
|
127
|
+
rollback: jest.fn(function () { return hang(); }),
|
|
128
|
+
commit: jest.fn(function () { return hang(); }),
|
|
129
|
+
};
|
|
130
|
+
db = {
|
|
131
|
+
runTransactionAsync: function (fn) { return __awaiter(void 0, void 0, void 0, function () {
|
|
132
|
+
return __generator(this, function (_a) {
|
|
133
|
+
switch (_a.label) {
|
|
134
|
+
case 0:
|
|
135
|
+
_a.trys.push([0, , 2, 3]);
|
|
136
|
+
return [4 /*yield*/, fn(transaction)];
|
|
137
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
138
|
+
case 2:
|
|
139
|
+
released.push('session');
|
|
140
|
+
return [7 /*endfinally*/];
|
|
141
|
+
case 3: return [2 /*return*/];
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}); },
|
|
145
|
+
};
|
|
146
|
+
driver = makeDriver({ operationDeadlineMs: 150, deadlineFailuresBeforeRecycle: 99 }, db);
|
|
147
|
+
return [4 /*yield*/, expect(driver.runDml(generateStatement)).rejects.toThrow(/deadline/)];
|
|
148
|
+
case 1:
|
|
149
|
+
_a.sent();
|
|
150
|
+
// dml deadline (~150ms) → bounded rollback deadline (~150ms more) → run function settles
|
|
151
|
+
// → the library's finally releases the session. A leak shows up as this wait timing out.
|
|
152
|
+
return [4 /*yield*/, waitFor(function () { return released.length === 1; }, 2000, 'session returned to the pool')];
|
|
153
|
+
case 2:
|
|
154
|
+
// dml deadline (~150ms) → bounded rollback deadline (~150ms more) → run function settles
|
|
155
|
+
// → the library's finally releases the session. A leak shows up as this wait timing out.
|
|
156
|
+
_a.sent();
|
|
157
|
+
expect(transaction.rollback).toHaveBeenCalled();
|
|
158
|
+
return [2 /*return*/];
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}); }, 5000);
|
|
162
|
+
test('channel-death recycle: 3 consecutive deadline failures recycle the client once; success resets the count', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
163
|
+
var hangOps, db, driver, recycleSpy, failingOp;
|
|
164
|
+
return __generator(this, function (_a) {
|
|
165
|
+
switch (_a.label) {
|
|
166
|
+
case 0:
|
|
167
|
+
hangOps = true;
|
|
168
|
+
db = { run: jest.fn(function () { return (hangOps ? hang() : Promise.resolve([[]])); }) };
|
|
169
|
+
driver = makeDriver({ operationDeadlineMs: 100, deadlineFailuresBeforeRecycle: 3 }, db);
|
|
170
|
+
recycleSpy = jest.spyOn(driver, 'recycleClient').mockImplementation(function () {
|
|
171
|
+
statics.CLIENT_GENERATION += 1;
|
|
172
|
+
});
|
|
173
|
+
failingOp = function () { return expect(driver.runQuery(generateStatement)).rejects.toThrow(/deadline/); };
|
|
174
|
+
return [4 /*yield*/, failingOp()];
|
|
175
|
+
case 1:
|
|
176
|
+
_a.sent();
|
|
177
|
+
return [4 /*yield*/, failingOp()];
|
|
178
|
+
case 2:
|
|
179
|
+
_a.sent();
|
|
180
|
+
expect(recycleSpy).not.toHaveBeenCalled();
|
|
181
|
+
// Any success resets the consecutive count.
|
|
182
|
+
hangOps = false;
|
|
183
|
+
return [4 /*yield*/, driver.runQuery(generateStatement)];
|
|
184
|
+
case 3:
|
|
185
|
+
_a.sent();
|
|
186
|
+
expect(statics.CONSECUTIVE_DEADLINE_FAILURES).toBe(0);
|
|
187
|
+
hangOps = true;
|
|
188
|
+
return [4 /*yield*/, failingOp()];
|
|
189
|
+
case 4:
|
|
190
|
+
_a.sent();
|
|
191
|
+
return [4 /*yield*/, failingOp()];
|
|
192
|
+
case 5:
|
|
193
|
+
_a.sent();
|
|
194
|
+
expect(recycleSpy).not.toHaveBeenCalled(); // the reset really pushed the threshold out
|
|
195
|
+
return [4 /*yield*/, failingOp()];
|
|
196
|
+
case 6:
|
|
197
|
+
_a.sent();
|
|
198
|
+
expect(recycleSpy).toHaveBeenCalledTimes(1); // 3rd consecutive failure → one recycle
|
|
199
|
+
expect(statics.CONSECUTIVE_DEADLINE_FAILURES).toBe(0);
|
|
200
|
+
return [2 /*return*/];
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
}); }, 10000);
|
|
204
|
+
test('deadline failures from a recycled (stale-generation) client never count against the fresh channel', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
205
|
+
var db, driver, recycleSpy, pending;
|
|
206
|
+
return __generator(this, function (_a) {
|
|
207
|
+
switch (_a.label) {
|
|
208
|
+
case 0:
|
|
209
|
+
db = { run: jest.fn(function () { return hang(); }) };
|
|
210
|
+
driver = makeDriver({ operationDeadlineMs: 100, deadlineFailuresBeforeRecycle: 1 }, db);
|
|
211
|
+
recycleSpy = jest.spyOn(driver, 'recycleClient').mockImplementation(function () {
|
|
212
|
+
statics.CLIENT_GENERATION += 1;
|
|
213
|
+
});
|
|
214
|
+
pending = expect(driver.runQuery(generateStatement)).rejects.toThrow(/deadline/);
|
|
215
|
+
// The client is recycled while the op is in flight — its failure belongs to the old channel.
|
|
216
|
+
statics.CLIENT_GENERATION += 1;
|
|
217
|
+
return [4 /*yield*/, pending];
|
|
218
|
+
case 1:
|
|
219
|
+
_a.sent();
|
|
220
|
+
expect(recycleSpy).not.toHaveBeenCalled();
|
|
221
|
+
expect(statics.CONSECUTIVE_DEADLINE_FAILURES).toBe(0);
|
|
222
|
+
return [2 /*return*/];
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
}); }, 5000);
|
|
226
|
+
});
|
|
227
|
+
//# sourceMappingURL=SpannerOperationDeadline.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpannerOperationDeadline.test.js","sourceRoot":"","sources":["../../test/SpannerOperationDeadline.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TransactionSafety.test.d.ts","sourceRoot":"","sources":["../../test/TransactionSafety.test.ts"],"names":[],"mappings":"AAKA,OAAO,yBAAyB,CAAC"}
|