@proteinjs/db 1.47.3 → 1.48.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.
@@ -37,12 +37,30 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.TransactionRunner = exports.getTransactionRunner = void 0;
40
+ var logger_1 = require("@proteinjs/logger");
40
41
  var Db_1 = require("../Db");
42
+ var Table_1 = require("../Table");
43
+ var TransactionContextFactory_1 = require("./TransactionContextFactory");
41
44
  var TransactionRunnerService_1 = require("../services/TransactionRunnerService");
42
45
  var getTransactionRunner = function () {
43
46
  return typeof self === 'undefined' ? new TransactionRunner() : (0, TransactionRunnerService_1.getTransactionRunnerService)();
44
47
  };
45
48
  exports.getTransactionRunner = getTransactionRunner;
49
+ /**
50
+ * Runs a client `Transaction`'s operations as one server-side transaction.
51
+ *
52
+ * A write may DECLARE the rows it depends on (`options.afterRows`): rows its operations
53
+ * reference whose own insert may still be in flight when this request arrives — a text update
54
+ * released by a page that was going away while its row's insert was still being served, a child
55
+ * row's insert whose root (its permission source, and the owner grant that commits with the
56
+ * root) is still landing. Without the declaration such a write ran to completion inside the
57
+ * insert's window and matched nothing, silently, or was refused at the door for a grant that was
58
+ * a moment from existing — and the page that could have retried was gone. The server outlives
59
+ * the page: it waits, bounded by the db driver's per-operation deadline, for every declared row to
60
+ * exist AND be visible to the caller (a read as the caller sees a row exactly when the caller's
61
+ * grant on its scope has committed), then runs the operations. A row that never appears fails the
62
+ * request with a plain clause.
63
+ */
46
64
  var TransactionRunner = /** @class */ (function () {
47
65
  function TransactionRunner() {
48
66
  this.serviceMetadata = {
@@ -50,43 +68,226 @@ var TransactionRunner = /** @class */ (function () {
50
68
  allUsers: true,
51
69
  },
52
70
  };
71
+ this.logger = new logger_1.Logger({ name: this.constructor.name });
53
72
  }
54
- TransactionRunner.prototype.run = function (ops) {
73
+ TransactionRunner.prototype.run = function (ops, options) {
74
+ var _a;
55
75
  return __awaiter(this, void 0, void 0, function () {
56
- var db;
76
+ var db, afterRows;
57
77
  var _this = this;
58
- return __generator(this, function (_a) {
59
- switch (_a.label) {
78
+ return __generator(this, function (_b) {
79
+ switch (_b.label) {
60
80
  case 0:
61
81
  db = (0, Db_1.getDb)();
62
- return [4 /*yield*/, db.runTransaction(function () { return __awaiter(_this, void 0, void 0, function () {
63
- var _i, ops_1, op;
64
- return __generator(this, function (_a) {
65
- switch (_a.label) {
66
- case 0:
67
- _i = 0, ops_1 = ops;
68
- _a.label = 1;
69
- case 1:
70
- if (!(_i < ops_1.length)) return [3 /*break*/, 4];
71
- op = ops_1[_i];
72
- return [4 /*yield*/, db[op.name].apply(db, op.args)];
73
- case 2:
74
- _a.sent();
75
- _a.label = 3;
76
- case 3:
77
- _i++;
78
- return [3 /*break*/, 1];
79
- case 4: return [2 /*return*/];
80
- }
81
- });
82
- }); })];
82
+ afterRows = (_a = options === null || options === void 0 ? void 0 : options.afterRows) !== null && _a !== void 0 ? _a : [];
83
+ if (!(afterRows.length > 0)) return [3 /*break*/, 2];
84
+ return [4 /*yield*/, this.awaitRows(ops, afterRows)];
83
85
  case 1:
84
- _a.sent();
86
+ _b.sent();
87
+ _b.label = 2;
88
+ case 2: return [4 /*yield*/, db.runTransaction(function () { return __awaiter(_this, void 0, void 0, function () {
89
+ var _i, ops_1, op;
90
+ return __generator(this, function (_a) {
91
+ switch (_a.label) {
92
+ case 0:
93
+ _i = 0, ops_1 = ops;
94
+ _a.label = 1;
95
+ case 1:
96
+ if (!(_i < ops_1.length)) return [3 /*break*/, 4];
97
+ op = ops_1[_i];
98
+ return [4 /*yield*/, db[op.name].apply(db, op.args)];
99
+ case 2:
100
+ _a.sent();
101
+ _a.label = 3;
102
+ case 3:
103
+ _i++;
104
+ return [3 /*break*/, 1];
105
+ case 4: return [2 /*return*/];
106
+ }
107
+ });
108
+ }); })];
109
+ case 3:
110
+ _b.sent();
85
111
  return [2 /*return*/];
86
112
  }
87
113
  });
88
114
  });
89
115
  };
116
+ /**
117
+ * Wait until every declared row exists and is visible to the caller, bounded by the db driver's
118
+ * per-operation deadline (`DbDriver.getOperationDeadlineMs`), read when the write waits. The
119
+ * bound is the ceiling for a row that NEVER comes — the named failure, never a hang. A
120
+ * dependency's insert lands in hundreds of milliseconds on a healthy link and in seconds on a
121
+ * degraded one (a root's birth of a few dozen sequential statements has taken 13 s), and the
122
+ * writes released behind it by a page that is gone have no second chance. The driver's deadline
123
+ * is how long the deployment lets one statement of that insert run before failing it: the wait
124
+ * takes its measure from there — one owner for the number, configured with the database — not
125
+ * from a number of its own. A write that waits here holds one request and a poll, nothing else.
126
+ *
127
+ * Each poll is a single-use strong read outside any transaction, so a commit is seen the moment
128
+ * it lands; the interval starts short and backs off so a dependency landing in hundreds of
129
+ * milliseconds is caught within tens.
130
+ */
131
+ TransactionRunner.prototype.awaitRows = function (ops, afterRows) {
132
+ var _a;
133
+ return __awaiter(this, void 0, void 0, function () {
134
+ var tablesById, unknown, db, boundMs, started, deadline, waiting, interval, polls, _loop_1, this_1, state_1;
135
+ return __generator(this, function (_b) {
136
+ switch (_b.label) {
137
+ case 0:
138
+ if ((_a = (0, TransactionContextFactory_1.getDefaultTransactionContextFactory)()) === null || _a === void 0 ? void 0 : _a.getTransactionContext().currentTransaction) {
139
+ throw new Error("TransactionRunner: afterRows cannot be honoured inside an ambient transaction \u2014 its reads would see the transaction's own snapshot, never a row committed after it began");
140
+ }
141
+ tablesById = TransactionRunner.rowsTheOperationsReference(ops);
142
+ unknown = afterRows.filter(function (id) { return !tablesById.has(id); });
143
+ if (unknown.length > 0) {
144
+ throw new Error("TransactionRunner: afterRows names rows none of the operations reference (".concat(unknown.join(', '), ") \u2014 the write was not run"));
145
+ }
146
+ db = (0, Db_1.getDb)();
147
+ boundMs = Db_1.Db.getDefaultDbDriver().getOperationDeadlineMs();
148
+ started = Date.now();
149
+ deadline = started + boundMs;
150
+ waiting = afterRows
151
+ .filter(function (id, index) { return afterRows.indexOf(id) === index; })
152
+ .map(function (id) { return ({ id: id, tables: tablesById.get(id).slice() }); });
153
+ interval = TransactionRunner.FIRST_POLL_INTERVAL_MS;
154
+ polls = 0;
155
+ _loop_1 = function () {
156
+ var _i, waiting_1, row, stillAbsent, _c, _d, table, waitedMs, line, now, absent;
157
+ return __generator(this, function (_e) {
158
+ switch (_e.label) {
159
+ case 0:
160
+ polls += 1;
161
+ _i = 0, waiting_1 = waiting;
162
+ _e.label = 1;
163
+ case 1:
164
+ if (!(_i < waiting_1.length)) return [3 /*break*/, 7];
165
+ row = waiting_1[_i];
166
+ stillAbsent = [];
167
+ _c = 0, _d = row.tables;
168
+ _e.label = 2;
169
+ case 2:
170
+ if (!(_c < _d.length)) return [3 /*break*/, 5];
171
+ table = _d[_c];
172
+ return [4 /*yield*/, db.get(table, { id: row.id })];
173
+ case 3:
174
+ if (!(_e.sent())) {
175
+ stillAbsent.push(table);
176
+ }
177
+ _e.label = 4;
178
+ case 4:
179
+ _c++;
180
+ return [3 /*break*/, 2];
181
+ case 5:
182
+ row.tables = stillAbsent;
183
+ _e.label = 6;
184
+ case 6:
185
+ _i++;
186
+ return [3 /*break*/, 1];
187
+ case 7:
188
+ waiting = waiting.filter(function (row) { return row.tables.length > 0; });
189
+ if (waiting.length === 0) {
190
+ waitedMs = Date.now() - started;
191
+ line = { message: "Declared rows present", obj: { afterRows: afterRows, waitedMs: waitedMs, polls: polls } };
192
+ if (polls > 1) {
193
+ this_1.logger.info(line);
194
+ }
195
+ else {
196
+ this_1.logger.debug(line);
197
+ }
198
+ return [2 /*return*/, { value: void 0 }];
199
+ }
200
+ now = Date.now();
201
+ if (now >= deadline) {
202
+ absent = waiting.map(function (row) { return row.tables.map(function (table) { return "".concat(table.name, ":").concat(row.id); }).join(', '); }).join(', ');
203
+ this_1.logger.warn({
204
+ message: "Declared rows absent at the bound \u2014 the write was not run",
205
+ obj: { absent: absent, boundMs: boundMs, waitedMs: now - started, polls: polls },
206
+ });
207
+ throw new Error("TransactionRunner: waited ".concat(boundMs, " ms for rows this write depends on to exist and be visible to the caller; still absent: ").concat(absent, " \u2014 the write was not run (the bound is the db driver's per-operation deadline)"));
208
+ }
209
+ return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, Math.min(interval, deadline - now)); })];
210
+ case 8:
211
+ _e.sent();
212
+ interval = Math.min(interval * 2, TransactionRunner.MAX_POLL_INTERVAL_MS);
213
+ return [2 /*return*/];
214
+ }
215
+ });
216
+ };
217
+ this_1 = this;
218
+ _b.label = 1;
219
+ case 1: return [5 /*yield**/, _loop_1()];
220
+ case 2:
221
+ state_1 = _b.sent();
222
+ if (typeof state_1 === "object")
223
+ return [2 /*return*/, state_1.value];
224
+ _b.label = 3;
225
+ case 3: return [3 /*break*/, 1];
226
+ case 4: return [2 /*return*/];
227
+ }
228
+ });
229
+ });
230
+ };
231
+ /**
232
+ * The rows the operations reference, by id → the table(s) they are read from: the permission
233
+ * source a row attaches to (an insert whose `permissionSource` is another row), the row an
234
+ * update / preserving update / membership update / delete targets. The rows the operations
235
+ * insert themselves are not dependencies.
236
+ */
237
+ TransactionRunner.rowsTheOperationsReference = function (ops) {
238
+ var _a, _b, _c;
239
+ var inserted = [];
240
+ var referenced = new Map();
241
+ var reference = function (table, id) {
242
+ if (!table || typeof id !== 'string') {
243
+ return;
244
+ }
245
+ var tables = referenced.get(id);
246
+ if (!tables) {
247
+ tables = [];
248
+ referenced.set(id, tables);
249
+ }
250
+ if (tables.indexOf(table) === -1) {
251
+ tables.push(table);
252
+ }
253
+ };
254
+ for (var _i = 0, ops_2 = ops; _i < ops_2.length; _i++) {
255
+ var op = ops_2[_i];
256
+ var args = op.args;
257
+ var table = args[0];
258
+ if (op.name === 'insert') {
259
+ var record = args[1];
260
+ if (record === null || record === void 0 ? void 0 : record.id) {
261
+ inserted.push(record.id);
262
+ }
263
+ var source = record === null || record === void 0 ? void 0 : record.permissionSource;
264
+ if ((source === null || source === void 0 ? void 0 : source._id) && source._id !== (record === null || record === void 0 ? void 0 : record.id)) {
265
+ var sourceTableName = (_a = record === null || record === void 0 ? void 0 : record.permissionSourceTable) !== null && _a !== void 0 ? _a : source._table;
266
+ reference(sourceTableName ? TransactionRunner.tableNamed(sourceTableName, table) : table, source._id);
267
+ }
268
+ }
269
+ else if (op.name === 'update' || op.name === 'updatePreserving') {
270
+ var record = args[1];
271
+ var query = args[2];
272
+ reference(table, (_b = record === null || record === void 0 ? void 0 : record.id) !== null && _b !== void 0 ? _b : (query && typeof query === 'object' && 'id' in query ? query.id : undefined));
273
+ }
274
+ else if (op.name === 'updateArrayMembership') {
275
+ reference(table, (_c = args[1]) === null || _c === void 0 ? void 0 : _c.recordId);
276
+ }
277
+ else if (op.name === 'delete') {
278
+ var query = args[1];
279
+ reference(table, query && typeof query === 'object' ? query.id : undefined);
280
+ }
281
+ }
282
+ inserted.forEach(function (id) { return referenced.delete(id); });
283
+ return referenced;
284
+ };
285
+ /** The table a permission source lives in: the insert's own table when it names the same one. */
286
+ TransactionRunner.tableNamed = function (tableName, inserting) {
287
+ return inserting && inserting.name === tableName ? inserting : (0, Table_1.tableByName)(tableName);
288
+ };
289
+ TransactionRunner.FIRST_POLL_INTERVAL_MS = 25;
290
+ TransactionRunner.MAX_POLL_INTERVAL_MS = 250;
90
291
  return TransactionRunner;
91
292
  }());
92
293
  exports.TransactionRunner = TransactionRunner;
@@ -1 +1 @@
1
- {"version":3,"file":"TransactionRunner.js","sourceRoot":"","sources":["../../../src/transaction/TransactionRunner.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4BAA8B;AAC9B,iFAA6G;AAGtG,IAAM,oBAAoB,GAAG;IAClC,OAAA,OAAO,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,iBAAiB,EAAE,CAAC,CAAC,CAAE,IAAA,sDAA2B,GAAwB;AAA5G,CAA4G,CAAC;AADlG,QAAA,oBAAoB,wBAC8E;AAE/G;IAAA;QACS,oBAAe,GAAG;YACvB,IAAI,EAAE;gBACJ,QAAQ,EAAE,IAAI;aACf;SACF,CAAC;IAWJ,CAAC;IATO,+BAAG,GAAT,UAAU,GAAqB;;;;;;;wBACvB,EAAE,GAAG,IAAA,UAAK,GAAE,CAAC;wBAEnB,qBAAM,EAAE,CAAC,cAAc,CAAC;;;;;kDACF,EAAH,WAAG;;;iDAAH,CAAA,iBAAG,CAAA;4CAAT,EAAE;4CACX,qBAAO,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,OAAX,EAAE,EAA0B,EAAE,CAAC,IAAI,GAAC;;4CAA3C,SAA2C,CAAC;;;4CAD7B,IAAG,CAAA;;;;;iCAGrB,CAAC,EAAA;;wBAJF,SAIE,CAAC;;;;;KACJ;IACH,wBAAC;AAAD,CAAC,AAhBD,IAgBC;AAhBY,8CAAiB"}
1
+ {"version":3,"file":"TransactionRunner.js","sourceRoot":"","sources":["../../../src/transaction/TransactionRunner.ts"],"names":[],"mappings":"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"}