@naturalcycles/datastore-lib 3.23.3 → 3.24.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/dist/datastore.db.d.ts +1 -0
- package/dist/datastore.db.js +36 -32
- package/package.json +1 -1
- package/src/datastore.db.ts +40 -35
package/dist/datastore.db.d.ts
CHANGED
|
@@ -57,4 +57,5 @@ export declare class DatastoreDB extends BaseCommonDB implements CommonDB {
|
|
|
57
57
|
getKey(key: Key): string | undefined;
|
|
58
58
|
getTables(): Promise<string[]>;
|
|
59
59
|
getTableSchema<ROW extends ObjectWithId>(table: string): Promise<JsonSchemaRootObject<ROW>>;
|
|
60
|
+
private getPRetryOptions;
|
|
60
61
|
}
|
package/dist/datastore.db.js
CHANGED
|
@@ -155,19 +155,7 @@ class DatastoreDB extends db_lib_1.BaseCommonDB {
|
|
|
155
155
|
const method = methodMap[opt.saveMethod || 'upsert'] || 'save';
|
|
156
156
|
const save = (0, js_lib_1.pRetryFn)(async (batch) => {
|
|
157
157
|
await (opt.tx || this.ds())[method](batch);
|
|
158
|
-
}, {
|
|
159
|
-
// Here we retry the GOAWAY errors that are somewhat common for Datastore
|
|
160
|
-
// Currently only retrying them here in .saveBatch(), cause probably they're only thrown when saving
|
|
161
|
-
predicate: err => RETRY_ON.some(s => err?.message?.includes(s)),
|
|
162
|
-
name: `DatastoreLib.saveBatch(${table})`,
|
|
163
|
-
maxAttempts: 5,
|
|
164
|
-
delay: 5000,
|
|
165
|
-
delayMultiplier: 2,
|
|
166
|
-
logFirstAttempt: false,
|
|
167
|
-
logFailures: true,
|
|
168
|
-
// logAll: true,
|
|
169
|
-
logger: this.cfg.logger,
|
|
170
|
-
});
|
|
158
|
+
}, this.getPRetryOptions(`DatastoreLib.saveBatch(${table})`));
|
|
171
159
|
try {
|
|
172
160
|
const chunks = (0, js_lib_1._chunk)(entities, MAX_ITEMS);
|
|
173
161
|
if (chunks.length === 1) {
|
|
@@ -203,27 +191,30 @@ class DatastoreDB extends db_lib_1.BaseCommonDB {
|
|
|
203
191
|
* https://cloud.google.com/datastore/docs/concepts/transactions#datastore-datastore-transactional-update-nodejs
|
|
204
192
|
*/
|
|
205
193
|
async commitTransaction(_tx, opt) {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
194
|
+
// Using Retry, because Datastore can throw errors like "too much contention" here
|
|
195
|
+
await (0, js_lib_1.pRetry)(async () => {
|
|
196
|
+
const tx = this.ds().transaction();
|
|
197
|
+
try {
|
|
198
|
+
await tx.run();
|
|
199
|
+
const ops = (0, db_lib_1.mergeDBOperations)(_tx.ops);
|
|
200
|
+
for await (const op of ops) {
|
|
201
|
+
if (op.type === 'saveBatch') {
|
|
202
|
+
await this.saveBatch(op.table, op.rows, { ...opt, tx });
|
|
203
|
+
}
|
|
204
|
+
else if (op.type === 'deleteByIds') {
|
|
205
|
+
await this.deleteByIds(op.table, op.ids, { ...opt, tx });
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
throw new Error(`DBOperation not supported: ${op.type}`);
|
|
209
|
+
}
|
|
219
210
|
}
|
|
211
|
+
await tx.commit();
|
|
220
212
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
213
|
+
catch (err) {
|
|
214
|
+
await tx.rollback();
|
|
215
|
+
throw err; // rethrow
|
|
216
|
+
}
|
|
217
|
+
}, this.getPRetryOptions(`DatastoreLib.commitTransaction`));
|
|
227
218
|
}
|
|
228
219
|
async getAllStats() {
|
|
229
220
|
const q = this.ds().createQuery('__Stat_Kind__');
|
|
@@ -356,5 +347,18 @@ class DatastoreDB extends db_lib_1.BaseCommonDB {
|
|
|
356
347
|
});
|
|
357
348
|
return s;
|
|
358
349
|
}
|
|
350
|
+
getPRetryOptions(name) {
|
|
351
|
+
return {
|
|
352
|
+
predicate: err => RETRY_ON.some(s => err?.message?.includes(s)),
|
|
353
|
+
name,
|
|
354
|
+
maxAttempts: 5,
|
|
355
|
+
delay: 5000,
|
|
356
|
+
delayMultiplier: 2,
|
|
357
|
+
logFirstAttempt: false,
|
|
358
|
+
logFailures: true,
|
|
359
|
+
// logAll: true,
|
|
360
|
+
logger: this.cfg.logger,
|
|
361
|
+
};
|
|
362
|
+
}
|
|
359
363
|
}
|
|
360
364
|
exports.DatastoreDB = DatastoreDB;
|
package/package.json
CHANGED
package/src/datastore.db.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
CommonDBSaveMethod,
|
|
7
7
|
DBQuery,
|
|
8
8
|
DBTransaction,
|
|
9
|
+
mergeDBOperations,
|
|
9
10
|
RunQueryResult,
|
|
10
11
|
} from '@naturalcycles/db-lib'
|
|
11
12
|
import {
|
|
@@ -25,6 +26,8 @@ import {
|
|
|
25
26
|
commonLoggerMinLevel,
|
|
26
27
|
pTimeout,
|
|
27
28
|
pRetryFn,
|
|
29
|
+
pRetry,
|
|
30
|
+
PRetryOptions,
|
|
28
31
|
} from '@naturalcycles/js-lib'
|
|
29
32
|
import { ReadableTyped } from '@naturalcycles/nodejs-lib'
|
|
30
33
|
import { boldWhite } from '@naturalcycles/nodejs-lib/dist/colors'
|
|
@@ -255,24 +258,9 @@ export class DatastoreDB extends BaseCommonDB implements CommonDB {
|
|
|
255
258
|
|
|
256
259
|
const method = methodMap[opt.saveMethod || 'upsert'] || 'save'
|
|
257
260
|
|
|
258
|
-
const save = pRetryFn(
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
},
|
|
262
|
-
{
|
|
263
|
-
// Here we retry the GOAWAY errors that are somewhat common for Datastore
|
|
264
|
-
// Currently only retrying them here in .saveBatch(), cause probably they're only thrown when saving
|
|
265
|
-
predicate: err => RETRY_ON.some(s => err?.message?.includes(s)),
|
|
266
|
-
name: `DatastoreLib.saveBatch(${table})`,
|
|
267
|
-
maxAttempts: 5,
|
|
268
|
-
delay: 5000,
|
|
269
|
-
delayMultiplier: 2,
|
|
270
|
-
logFirstAttempt: false,
|
|
271
|
-
logFailures: true,
|
|
272
|
-
// logAll: true,
|
|
273
|
-
logger: this.cfg.logger,
|
|
274
|
-
},
|
|
275
|
-
)
|
|
261
|
+
const save = pRetryFn(async (batch: DatastorePayload<ROW>[]) => {
|
|
262
|
+
await (opt.tx || this.ds())[method](batch)
|
|
263
|
+
}, this.getPRetryOptions(`DatastoreLib.saveBatch(${table})`))
|
|
276
264
|
|
|
277
265
|
try {
|
|
278
266
|
const chunks = _chunk(entities, MAX_ITEMS)
|
|
@@ -328,28 +316,31 @@ export class DatastoreDB extends BaseCommonDB implements CommonDB {
|
|
|
328
316
|
_tx: DBTransaction,
|
|
329
317
|
opt?: DatastoreDBSaveOptions,
|
|
330
318
|
): Promise<void> {
|
|
331
|
-
|
|
319
|
+
// Using Retry, because Datastore can throw errors like "too much contention" here
|
|
320
|
+
await pRetry(async () => {
|
|
321
|
+
const tx = this.ds().transaction()
|
|
332
322
|
|
|
333
|
-
|
|
334
|
-
|
|
323
|
+
try {
|
|
324
|
+
await tx.run()
|
|
335
325
|
|
|
336
|
-
|
|
326
|
+
const ops = mergeDBOperations(_tx.ops)
|
|
337
327
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
328
|
+
for await (const op of ops) {
|
|
329
|
+
if (op.type === 'saveBatch') {
|
|
330
|
+
await this.saveBatch(op.table, op.rows, { ...opt, tx })
|
|
331
|
+
} else if (op.type === 'deleteByIds') {
|
|
332
|
+
await this.deleteByIds(op.table, op.ids, { ...opt, tx })
|
|
333
|
+
} else {
|
|
334
|
+
throw new Error(`DBOperation not supported: ${(op as any).type}`)
|
|
335
|
+
}
|
|
345
336
|
}
|
|
346
|
-
}
|
|
347
337
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
338
|
+
await tx.commit()
|
|
339
|
+
} catch (err) {
|
|
340
|
+
await tx.rollback()
|
|
341
|
+
throw err // rethrow
|
|
342
|
+
}
|
|
343
|
+
}, this.getPRetryOptions(`DatastoreLib.commitTransaction`))
|
|
353
344
|
}
|
|
354
345
|
|
|
355
346
|
async getAllStats(): Promise<DatastoreStats[]> {
|
|
@@ -496,4 +487,18 @@ export class DatastoreDB extends BaseCommonDB implements CommonDB {
|
|
|
496
487
|
|
|
497
488
|
return s
|
|
498
489
|
}
|
|
490
|
+
|
|
491
|
+
private getPRetryOptions(name: string): PRetryOptions {
|
|
492
|
+
return {
|
|
493
|
+
predicate: err => RETRY_ON.some(s => err?.message?.includes(s)),
|
|
494
|
+
name,
|
|
495
|
+
maxAttempts: 5,
|
|
496
|
+
delay: 5000,
|
|
497
|
+
delayMultiplier: 2,
|
|
498
|
+
logFirstAttempt: false,
|
|
499
|
+
logFailures: true,
|
|
500
|
+
// logAll: true,
|
|
501
|
+
logger: this.cfg.logger,
|
|
502
|
+
}
|
|
503
|
+
}
|
|
499
504
|
}
|