datastore-api 1.3.0 → 1.7.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 +28 -0
- package/README.md +23 -0
- package/build/main/lib/dstore-api.d.ts +22 -10
- package/build/main/lib/dstore-api.js +71 -14
- package/build/main/lib/dstore-api.spec.js +51 -129
- package/build/module/lib/dstore-api.d.ts +22 -10
- package/build/module/lib/dstore-api.js +71 -14
- package/build/module/lib/dstore-api.spec.js +48 -128
- package/package.json +9 -8
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [1.7.0](https://github.com/mdornseif/datastore-api/compare/v1.6.0...v1.7.0) (2022-01-30)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* use prop-client to collect datastore metrics ([e55ff06](https://github.com/mdornseif/datastore-api/commit/e55ff06c8e069ca0df798c1e1f34c2eb9bf9079b))
|
|
11
|
+
|
|
12
|
+
## [1.6.0](https://github.com/mdornseif/datastore-api/compare/v1.5.0...v1.6.0) (2022-01-10)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* catch incomplete keys before trying to update the datastore ([1132e3b](https://github.com/mdornseif/datastore-api/commit/1132e3b52913d83b189c7bf94101c6df162f87df))
|
|
18
|
+
|
|
19
|
+
## [1.5.0](https://github.com/mdornseif/datastore-api/compare/v1.4.0...v1.5.0) (2022-01-06)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Features
|
|
23
|
+
|
|
24
|
+
* provide _keyStr also in queries ([fe7e90b](https://github.com/mdornseif/datastore-api/commit/fe7e90b3011e08de552e1b4e35b1ad110efa6b1b))
|
|
25
|
+
|
|
26
|
+
## [1.4.0](https://github.com/mdornseif/datastore-api/compare/v1.3.0...v1.4.0) (2022-01-04)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### Features
|
|
30
|
+
|
|
31
|
+
* save() adds _keyStr the same way get() does ([f4f6452](https://github.com/mdornseif/datastore-api/commit/f4f6452c77046c0ee8d0b6ddfe2ec6744a4968bd))
|
|
32
|
+
|
|
5
33
|
## [1.3.0](https://github.com/mdornseif/datastore-api/compare/v1.2.0...v1.3.0) (2022-01-03)
|
|
6
34
|
|
|
7
35
|
|
package/README.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
[](https://npmjs.org/datastore-api)
|
|
2
|
+
[](https://github.com/mdornseif/datastore-api/blob/master/LICENSE)
|
|
3
|
+
[](https://npmcharts.com/compare/datastore-api)
|
|
4
|
+
|
|
1
5
|
# datastore-api
|
|
2
6
|
|
|
3
7
|
Simplified, more consistent API for Google Cloud Datastore.
|
|
@@ -24,6 +28,25 @@ Find the full documentation [here](http://mdornseif.io/datastore-api/classes/Dst
|
|
|
24
28
|
|
|
25
29
|
See [the API documentation](http://mdornseif.io/datastore-api/classes/Dstore.html) for Details, [Github](https://github.com/mdornseif/datastore-api) for source.
|
|
26
30
|
|
|
31
|
+
## Metrics
|
|
32
|
+
|
|
33
|
+
Datastore-API is instrumented with [prom-client](https://github.com/siimon/prom-client). Metrics are all prefixed with `dstore_`.
|
|
34
|
+
|
|
35
|
+
In an express based Application you can make them available like this:
|
|
36
|
+
|
|
37
|
+
```js
|
|
38
|
+
import promClient from 'prom-client';
|
|
39
|
+
|
|
40
|
+
server.get('/metrics', async (req, res) => {
|
|
41
|
+
try {
|
|
42
|
+
res.set('Content-Type', promClient.register.contentType);
|
|
43
|
+
res.end(await promClient.register.metrics());
|
|
44
|
+
} catch (ex) {
|
|
45
|
+
res.status(500).end(ex);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
27
50
|
## See also
|
|
28
51
|
|
|
29
52
|
- Google Documentation
|
|
@@ -4,6 +4,10 @@ import { Operator, RunQueryResponse } from '@google-cloud/datastore/build/src/qu
|
|
|
4
4
|
import { CommitResponse } from '@google-cloud/datastore/build/src/request';
|
|
5
5
|
/** @ignore */
|
|
6
6
|
export { Datastore, Key, PathType, Query, Transaction, } from '@google-cloud/datastore';
|
|
7
|
+
/** Use instead of Datastore.KEY
|
|
8
|
+
*
|
|
9
|
+
* Even better: use `_key` instead.
|
|
10
|
+
*/
|
|
7
11
|
export declare const KEYSYM: symbol;
|
|
8
12
|
export declare type IGqlFilterTypes = boolean | string | number;
|
|
9
13
|
export declare type IGqlFilterSpec = {
|
|
@@ -19,8 +23,7 @@ export interface IDstoreEntryWithoutKey {
|
|
|
19
23
|
[key: string]: DstorePropertyValues;
|
|
20
24
|
}
|
|
21
25
|
/** Represents what is actually stored inside the Datastore, called "Entity" by Google
|
|
22
|
-
[@google-cloud/datastore](https://github.com/googleapis/nodejs-datastore#readme) adds `[Datastore.KEY]`. Using ES6 Symbols presents all kinds of hurdles, especially when you try to serialize into a cache. So we add the property _keyStr which contains the encoded
|
|
23
|
-
to reconstruct `[Datastore.KEY]`, if you use [[Dstore.readKey]].
|
|
26
|
+
[@google-cloud/datastore](https://github.com/googleapis/nodejs-datastore#readme) adds `[Datastore.KEY]`. Using ES6 Symbols presents all kinds of hurdles, especially when you try to serialize into a cache. So we add the property _keyStr which contains the encoded key. It is automatically used to reconstruct `[Datastore.KEY]`, if you use [[Dstore.readKey]].
|
|
24
27
|
*/
|
|
25
28
|
export interface IDstoreEntry extends IDstoreEntryWithoutKey {
|
|
26
29
|
readonly [Datastore.KEY]?: Key;
|
|
@@ -32,7 +35,10 @@ export interface IDstoreEntry extends IDstoreEntryWithoutKey {
|
|
|
32
35
|
/** Represents the thing you pass to the save method. Also called "Entity" by Google */
|
|
33
36
|
export declare type DstoreSaveEntity = {
|
|
34
37
|
key: Key;
|
|
35
|
-
data: Omit<IDstoreEntry, '_keyStr' | Datastore['KEY']
|
|
38
|
+
data: Omit<IDstoreEntry, '_keyStr' | Datastore['KEY']> & Partial<{
|
|
39
|
+
_keyStr: string;
|
|
40
|
+
[Datastore.KEY]: Key;
|
|
41
|
+
}>;
|
|
36
42
|
method?: 'insert' | 'update' | 'upsert';
|
|
37
43
|
excludeLargeProperties?: boolean;
|
|
38
44
|
excludeFromIndexes?: readonly string[];
|
|
@@ -211,7 +217,7 @@ export declare class Dstore implements IDstore {
|
|
|
211
217
|
*
|
|
212
218
|
* If the Datastore generates a new ID because of an incomplete [[Key]] *on first save* it will return an large integer as [[Key.id]].
|
|
213
219
|
* On every subsequent `save()` an string encoded number representation is returned.
|
|
214
|
-
* Dstore normalizes that and always
|
|
220
|
+
* @todo Dstore should normalizes that and always return an string encoded number representation.
|
|
215
221
|
*
|
|
216
222
|
* Each [[DstoreSaveEntity]] can have an `excludeFromIndexes` property which is somewhat underdocumented.
|
|
217
223
|
* It can use something like JSON-Path notation
|
|
@@ -240,6 +246,8 @@ export declare class Dstore implements IDstore {
|
|
|
240
246
|
*
|
|
241
247
|
* For handling of incomplete [[Key]]s see [[save]].
|
|
242
248
|
*
|
|
249
|
+
* This function can be completely emulated by using [[save]] with `method: 'insert'` inside each [[DstoreSaveEntity]].
|
|
250
|
+
*
|
|
243
251
|
* @throws [[DstoreError]]
|
|
244
252
|
* @category Datastore Drop-In
|
|
245
253
|
*/
|
|
@@ -254,15 +262,17 @@ export declare class Dstore implements IDstore {
|
|
|
254
262
|
* It throws an [[DstoreError]] if there is no Entity with the same [[Key]] in the Datastore. `update()` *overwrites all existing data* for that [[Key]].
|
|
255
263
|
* There was an alpha functionality called `merge()` in the Datastore which read an Entity, merged it with the new data and wrote it back, but this was never documented.
|
|
256
264
|
*
|
|
257
|
-
* `update()` is idempotent.
|
|
265
|
+
* `update()` is idempotent. Updating the same [[Key]] twice is no error.
|
|
266
|
+
*
|
|
267
|
+
* This function can be completely emulated by using [[save]] with `method: 'update'` inside each [[DstoreSaveEntity]].
|
|
258
268
|
*
|
|
259
269
|
* @throws [[DstoreError]]
|
|
260
270
|
* @category Datastore Drop-In
|
|
261
271
|
*/
|
|
262
272
|
update(entities: readonly DstoreSaveEntity[]): Promise<CommitResponse | undefined>;
|
|
263
|
-
/** `delete()` is compatible to [Datastore.
|
|
273
|
+
/** `delete()` is compatible to [Datastore.delete()].
|
|
264
274
|
*
|
|
265
|
-
* Unfortunately currently (late 2021) there is no formal documentation from Google on [Datastore.
|
|
275
|
+
* Unfortunately currently (late 2021) there is no formal documentation from Google on [Datastore.delete()].
|
|
266
276
|
*
|
|
267
277
|
* The single Parameter is a list of [[Key]]s.
|
|
268
278
|
* If called within a transaction it returns `undefined`.
|
|
@@ -299,8 +309,6 @@ export declare class Dstore implements IDstore {
|
|
|
299
309
|
allocateOneId(kindName?: string): Promise<string>;
|
|
300
310
|
/** This tries to give high level access to transactions.
|
|
301
311
|
|
|
302
|
-
Be aware that Transactions differ considerable between Master-Slave Datastore (very old), High Replication Datastore (old, later called [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/cloud-datastore-transactions)) and [Firestore in Datastore Mode](https://cloud.google.com/datastore/docs/firestore-or-datastore#in_datastore_mode) (current).
|
|
303
|
-
|
|
304
312
|
So called "Gross Group Transactions" are always enabled. Transactions are never Cross Project. `runInTransaction()` works only if you use the same [[KvStore] instance for all access within the Transaction.
|
|
305
313
|
|
|
306
314
|
[[runInTransaction]] is modelled after Python 2.7 [ndb's `@ndb.transactional` feature](https://cloud.google.com/appengine/docs/standard/python/ndb/transactions). This is based on node's [AsyncLocalStorage](https://nodejs.org/docs/latest-v14.x/api/async_hooks.html).
|
|
@@ -308,7 +316,11 @@ export declare class Dstore implements IDstore {
|
|
|
308
316
|
Transactions frequently fail if you try to access the same data via in a transaction. See the [Documentation on Locking](https://cloud.google.com/datastore/docs/concepts/transactions#transaction_locks) for further reference. You are advised to use [p-limit](https://github.com/sindresorhus/p-limit)(1) to serialize transactions touching the same resource. This should work nicely with node's single process model. It is a much bigger problem on shared-nothing approaches, like Python on App Engine.
|
|
309
317
|
|
|
310
318
|
Transactions might be wrapped in [p-retry](https://github.com/sindresorhus/p-retry) to implement automatically retrying them with exponential back-off should they fail due to contention.
|
|
311
|
-
|
|
319
|
+
|
|
320
|
+
Be aware that Transactions differ considerable between Master-Slave Datastore (very old), High Replication Datastore (old, later called [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/cloud-datastore-transactions)) and [Firestore in Datastore Mode](https://cloud.google.com/datastore/docs/firestore-or-datastore#in_datastore_mode) (current).
|
|
321
|
+
|
|
322
|
+
Most Applications today are running on "Firestore in Datastore Mode". Beware that the Datastore-Emulator fails with `error: 3 INVALID_ARGUMENT: Only ancestor queries are allowed inside transactions.` during [[runQuery]] while the Datastore on Google Infrastructure does not have such an restriction anymore as of 2022.
|
|
323
|
+
*/
|
|
312
324
|
runInTransaction<T>(func: () => Promise<T>): Promise<T>;
|
|
313
325
|
}
|
|
314
326
|
export declare class DstoreError extends Error {
|
|
@@ -19,6 +19,7 @@ const datastore_1 = require("@google-cloud/datastore");
|
|
|
19
19
|
const entity_1 = require("@google-cloud/datastore/build/src/entity");
|
|
20
20
|
const assertate_1 = require("assertate");
|
|
21
21
|
const debug_1 = __importDefault(require("debug"));
|
|
22
|
+
const prom_client_1 = __importDefault(require("prom-client"));
|
|
22
23
|
/** @ignore */
|
|
23
24
|
var datastore_2 = require("@google-cloud/datastore");
|
|
24
25
|
Object.defineProperty(exports, "Datastore", { enumerable: true, get: function () { return datastore_2.Datastore; } });
|
|
@@ -28,11 +29,33 @@ Object.defineProperty(exports, "Transaction", { enumerable: true, get: function
|
|
|
28
29
|
/** @ignore */
|
|
29
30
|
const debug = (0, debug_1.default)('ds:api');
|
|
30
31
|
/** @ignore */
|
|
32
|
+
const transactionAsyncLocalStorage = new async_hooks_1.AsyncLocalStorage();
|
|
33
|
+
/** @ignore */
|
|
34
|
+
const metricGetHistogram = new prom_client_1.default.Histogram({
|
|
35
|
+
name: 'dstore_get_duration_seconds',
|
|
36
|
+
help: 'How long did Datastore gets take?',
|
|
37
|
+
labelNames: ['kindName'],
|
|
38
|
+
});
|
|
39
|
+
/** @ignore */
|
|
40
|
+
const metricSaveHistogram = new prom_client_1.default.Histogram({
|
|
41
|
+
name: 'dstore_save_duration_seconds',
|
|
42
|
+
help: 'How long did Datastore saves(insert/update/upsert) take?',
|
|
43
|
+
});
|
|
44
|
+
/** @ignore */
|
|
45
|
+
const metricDeleteHistogram = new prom_client_1.default.Histogram({
|
|
46
|
+
name: 'dstore_delete_duration_seconds',
|
|
47
|
+
help: 'How long did Datastore delete take?',
|
|
48
|
+
});
|
|
49
|
+
/** @ignore */
|
|
50
|
+
const metricQueryHistogram = new prom_client_1.default.Histogram({
|
|
51
|
+
name: 'dstore_query_duration_seconds',
|
|
52
|
+
help: 'How long did Datastore queries take?',
|
|
53
|
+
labelNames: ['kindName'],
|
|
54
|
+
});
|
|
31
55
|
/** Use instead of Datastore.KEY
|
|
32
56
|
*
|
|
33
57
|
* Even better: use `_key` instead.
|
|
34
58
|
*/
|
|
35
|
-
const transactionAsyncLocalStorage = new async_hooks_1.AsyncLocalStorage();
|
|
36
59
|
exports.KEYSYM = datastore_1.Datastore.KEY;
|
|
37
60
|
/** Dstore implements a slightly more accessible version of the [Google Cloud Datastore: Node.js Client](https://cloud.google.com/nodejs/docs/reference/datastore/latest)
|
|
38
61
|
|
|
@@ -165,9 +188,12 @@ class Dstore {
|
|
|
165
188
|
* @category Datastore Drop-In
|
|
166
189
|
*/
|
|
167
190
|
async get(key) {
|
|
191
|
+
const metricEnd = metricGetHistogram.startTimer();
|
|
168
192
|
(0, assertate_1.assertIsObject)(key);
|
|
169
193
|
(0, assertate_1.assert)(!Array.isArray(key));
|
|
194
|
+
(0, assertate_1.assert)(key.path.length % 2 == 0, `key.path must be complete: ${JSON.stringify(key.path)}`);
|
|
170
195
|
const result = await this.getMulti([key]);
|
|
196
|
+
metricEnd({ kindName: key.kind });
|
|
171
197
|
return (result === null || result === void 0 ? void 0 : result[0]) || null;
|
|
172
198
|
}
|
|
173
199
|
/** `getMulti()` reads several [[IDstoreEntry]]s from the Datastore.
|
|
@@ -239,7 +265,7 @@ class Dstore {
|
|
|
239
265
|
*
|
|
240
266
|
* If the Datastore generates a new ID because of an incomplete [[Key]] *on first save* it will return an large integer as [[Key.id]].
|
|
241
267
|
* On every subsequent `save()` an string encoded number representation is returned.
|
|
242
|
-
* Dstore normalizes that and always
|
|
268
|
+
* @todo Dstore should normalizes that and always return an string encoded number representation.
|
|
243
269
|
*
|
|
244
270
|
* Each [[DstoreSaveEntity]] can have an `excludeFromIndexes` property which is somewhat underdocumented.
|
|
245
271
|
* It can use something like JSON-Path notation
|
|
@@ -260,6 +286,7 @@ class Dstore {
|
|
|
260
286
|
async save(entities) {
|
|
261
287
|
(0, assertate_1.assertIsArray)(entities);
|
|
262
288
|
try {
|
|
289
|
+
const metricEnd = metricSaveHistogram.startTimer();
|
|
263
290
|
// Within Transaction we don't get any answer here!
|
|
264
291
|
// [ { mutationResults: [ [Object], [Object] ], indexUpdates: 51 } ]
|
|
265
292
|
for (const e of entities) {
|
|
@@ -271,7 +298,13 @@ class Dstore {
|
|
|
271
298
|
? true
|
|
272
299
|
: e.excludeLargeProperties;
|
|
273
300
|
}
|
|
274
|
-
|
|
301
|
+
const ret = (await this.getDoT().save(entities)) || undefined;
|
|
302
|
+
for (const e of entities) {
|
|
303
|
+
e.data[datastore_1.Datastore.KEY] = e.key;
|
|
304
|
+
this.fixKeys([e.data]);
|
|
305
|
+
}
|
|
306
|
+
metricEnd();
|
|
307
|
+
return ret;
|
|
275
308
|
}
|
|
276
309
|
catch (error) {
|
|
277
310
|
throw process.env.NODE_ENV === 'test'
|
|
@@ -289,13 +322,18 @@ class Dstore {
|
|
|
289
322
|
*
|
|
290
323
|
* For handling of incomplete [[Key]]s see [[save]].
|
|
291
324
|
*
|
|
325
|
+
* This function can be completely emulated by using [[save]] with `method: 'insert'` inside each [[DstoreSaveEntity]].
|
|
326
|
+
*
|
|
292
327
|
* @throws [[DstoreError]]
|
|
293
328
|
* @category Datastore Drop-In
|
|
294
329
|
*/
|
|
295
330
|
async insert(entities) {
|
|
296
331
|
(0, assertate_1.assertIsArray)(entities);
|
|
297
332
|
try {
|
|
298
|
-
|
|
333
|
+
const metricEnd = metricSaveHistogram.startTimer();
|
|
334
|
+
const ret = (await this.getDoT().insert(entities)) || undefined;
|
|
335
|
+
metricEnd();
|
|
336
|
+
return ret;
|
|
299
337
|
}
|
|
300
338
|
catch (error) {
|
|
301
339
|
// console.error(error)
|
|
@@ -314,15 +352,25 @@ class Dstore {
|
|
|
314
352
|
* It throws an [[DstoreError]] if there is no Entity with the same [[Key]] in the Datastore. `update()` *overwrites all existing data* for that [[Key]].
|
|
315
353
|
* There was an alpha functionality called `merge()` in the Datastore which read an Entity, merged it with the new data and wrote it back, but this was never documented.
|
|
316
354
|
*
|
|
317
|
-
* `update()` is idempotent.
|
|
355
|
+
* `update()` is idempotent. Updating the same [[Key]] twice is no error.
|
|
356
|
+
*
|
|
357
|
+
* This function can be completely emulated by using [[save]] with `method: 'update'` inside each [[DstoreSaveEntity]].
|
|
318
358
|
*
|
|
319
359
|
* @throws [[DstoreError]]
|
|
320
360
|
* @category Datastore Drop-In
|
|
321
361
|
*/
|
|
322
362
|
async update(entities) {
|
|
323
363
|
(0, assertate_1.assertIsArray)(entities);
|
|
364
|
+
entities.forEach((entity) => (0, assertate_1.assertIsObject)(entity.key));
|
|
365
|
+
entities.forEach((entity) => (0, assertate_1.assert)(entity.key.path.length % 2 == 0, `entity.key.path must be complete: ${JSON.stringify([
|
|
366
|
+
entity.key.path,
|
|
367
|
+
entity,
|
|
368
|
+
])}`));
|
|
324
369
|
try {
|
|
325
|
-
|
|
370
|
+
const metricEnd = metricSaveHistogram.startTimer();
|
|
371
|
+
const ret = (await this.getDoT().update(entities)) || undefined;
|
|
372
|
+
metricEnd();
|
|
373
|
+
return ret;
|
|
326
374
|
}
|
|
327
375
|
catch (error) {
|
|
328
376
|
// console.error(error)
|
|
@@ -331,9 +379,9 @@ class Dstore {
|
|
|
331
379
|
: new DstoreError('datastore.update error', error);
|
|
332
380
|
}
|
|
333
381
|
}
|
|
334
|
-
/** `delete()` is compatible to [Datastore.
|
|
382
|
+
/** `delete()` is compatible to [Datastore.delete()].
|
|
335
383
|
*
|
|
336
|
-
* Unfortunately currently (late 2021) there is no formal documentation from Google on [Datastore.
|
|
384
|
+
* Unfortunately currently (late 2021) there is no formal documentation from Google on [Datastore.delete()].
|
|
337
385
|
*
|
|
338
386
|
* The single Parameter is a list of [[Key]]s.
|
|
339
387
|
* If called within a transaction it returns `undefined`.
|
|
@@ -347,8 +395,12 @@ class Dstore {
|
|
|
347
395
|
async delete(keys) {
|
|
348
396
|
(0, assertate_1.assertIsArray)(keys);
|
|
349
397
|
keys.forEach((key) => (0, assertate_1.assertIsObject)(key));
|
|
398
|
+
keys.forEach((key) => (0, assertate_1.assert)(key.path.length % 2 == 0, `key.path must be complete: ${JSON.stringify(key.path)}`));
|
|
350
399
|
try {
|
|
351
|
-
|
|
400
|
+
const metricEnd = metricDeleteHistogram.startTimer();
|
|
401
|
+
const ret = (await this.getDoT().delete(keys)) || undefined;
|
|
402
|
+
metricEnd();
|
|
403
|
+
return ret;
|
|
352
404
|
}
|
|
353
405
|
catch (error) {
|
|
354
406
|
// console.error(error)
|
|
@@ -375,7 +427,10 @@ class Dstore {
|
|
|
375
427
|
}
|
|
376
428
|
async runQuery(query) {
|
|
377
429
|
try {
|
|
378
|
-
|
|
430
|
+
const metricEnd = metricQueryHistogram.startTimer();
|
|
431
|
+
const [entities, info] = await this.getDoT().runQuery(query);
|
|
432
|
+
metricEnd();
|
|
433
|
+
return [this.fixKeys(entities), info];
|
|
379
434
|
}
|
|
380
435
|
catch (error) {
|
|
381
436
|
throw new DstoreError('datastore.runQuery error', error);
|
|
@@ -434,8 +489,6 @@ class Dstore {
|
|
|
434
489
|
}
|
|
435
490
|
/** This tries to give high level access to transactions.
|
|
436
491
|
|
|
437
|
-
Be aware that Transactions differ considerable between Master-Slave Datastore (very old), High Replication Datastore (old, later called [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/cloud-datastore-transactions)) and [Firestore in Datastore Mode](https://cloud.google.com/datastore/docs/firestore-or-datastore#in_datastore_mode) (current).
|
|
438
|
-
|
|
439
492
|
So called "Gross Group Transactions" are always enabled. Transactions are never Cross Project. `runInTransaction()` works only if you use the same [[KvStore] instance for all access within the Transaction.
|
|
440
493
|
|
|
441
494
|
[[runInTransaction]] is modelled after Python 2.7 [ndb's `@ndb.transactional` feature](https://cloud.google.com/appengine/docs/standard/python/ndb/transactions). This is based on node's [AsyncLocalStorage](https://nodejs.org/docs/latest-v14.x/api/async_hooks.html).
|
|
@@ -443,7 +496,11 @@ class Dstore {
|
|
|
443
496
|
Transactions frequently fail if you try to access the same data via in a transaction. See the [Documentation on Locking](https://cloud.google.com/datastore/docs/concepts/transactions#transaction_locks) for further reference. You are advised to use [p-limit](https://github.com/sindresorhus/p-limit)(1) to serialize transactions touching the same resource. This should work nicely with node's single process model. It is a much bigger problem on shared-nothing approaches, like Python on App Engine.
|
|
444
497
|
|
|
445
498
|
Transactions might be wrapped in [p-retry](https://github.com/sindresorhus/p-retry) to implement automatically retrying them with exponential back-off should they fail due to contention.
|
|
446
|
-
|
|
499
|
+
|
|
500
|
+
Be aware that Transactions differ considerable between Master-Slave Datastore (very old), High Replication Datastore (old, later called [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/cloud-datastore-transactions)) and [Firestore in Datastore Mode](https://cloud.google.com/datastore/docs/firestore-or-datastore#in_datastore_mode) (current).
|
|
501
|
+
|
|
502
|
+
Most Applications today are running on "Firestore in Datastore Mode". Beware that the Datastore-Emulator fails with `error: 3 INVALID_ARGUMENT: Only ancestor queries are allowed inside transactions.` during [[runQuery]] while the Datastore on Google Infrastructure does not have such an restriction anymore as of 2022.
|
|
503
|
+
*/
|
|
447
504
|
async runInTransaction(func) {
|
|
448
505
|
let ret;
|
|
449
506
|
const transaction = this.datastore.transaction();
|
|
@@ -492,4 +549,4 @@ class DstoreError extends Error {
|
|
|
492
549
|
}
|
|
493
550
|
}
|
|
494
551
|
exports.DstoreError = DstoreError;
|
|
495
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHN0b3JlLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvZHN0b3JlLWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7OztHQVNHOzs7Ozs7QUFFSCw2Q0FBZ0Q7QUFFaEQsdURBTWlDO0FBQ2pDLHFFQUFrRTtBQU1sRSx5Q0FPbUI7QUFDbkIsa0RBQTBCO0FBRzFCLGNBQWM7QUFDZCxxREFNaUM7QUFML0Isc0dBQUEsU0FBUyxPQUFBO0FBQ1QsZ0dBQUEsR0FBRyxPQUFBO0FBRUgsa0dBQUEsS0FBSyxPQUFBO0FBQ0wsd0dBQUEsV0FBVyxPQUFBO0FBR2IsY0FBYztBQUNkLE1BQU0sS0FBSyxHQUFHLElBQUEsZUFBSyxFQUFDLFFBQVEsQ0FBQyxDQUFDO0FBRTlCLGNBQWM7QUFFZDs7O0dBR0c7QUFDSCxNQUFNLDRCQUE0QixHQUFHLElBQUksK0JBQWlCLEVBQUUsQ0FBQztBQUVoRCxRQUFBLE1BQU0sR0FBRyxxQkFBUyxDQUFDLEdBQUcsQ0FBQztBQXFGcEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7RUFzQkU7QUFDRixNQUFhLE1BQU07SUFHakI7Ozs7Ozs7Ozs7Ozs7O01BY0U7SUFDRixZQUNXLFNBQW9CLEVBQ3BCLFNBQWtCLEVBQ2xCLE1BQWU7UUFGZixjQUFTLEdBQVQsU0FBUyxDQUFXO1FBQ3BCLGNBQVMsR0FBVCxTQUFTLENBQVM7UUFDbEIsV0FBTSxHQUFOLE1BQU0sQ0FBUztRQXBCVCxlQUFVLEdBQUcsSUFBSSxlQUFNLENBQUMsVUFBVSxFQUFFLENBQUM7UUFzQnBELElBQUEsMEJBQWMsRUFBQyxTQUFTLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRUQscURBQXFEO0lBQzdDLE1BQU07UUFDWixPQUFPLENBQ0osNEJBQTRCLENBQUMsUUFBUSxFQUFrQixJQUFJLElBQUksQ0FBQyxTQUFTLENBQzNFLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILEdBQUcsQ0FB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
|
|
552
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHN0b3JlLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvZHN0b3JlLWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7OztHQVNHOzs7Ozs7QUFFSCw2Q0FBZ0Q7QUFFaEQsdURBTWlDO0FBQ2pDLHFFQUEwRTtBQU8xRSx5Q0FPbUI7QUFDbkIsa0RBQTBCO0FBQzFCLDhEQUFxQztBQUdyQyxjQUFjO0FBQ2QscURBTWlDO0FBTC9CLHNHQUFBLFNBQVMsT0FBQTtBQUNULGdHQUFBLEdBQUcsT0FBQTtBQUVILGtHQUFBLEtBQUssT0FBQTtBQUNMLHdHQUFBLFdBQVcsT0FBQTtBQUdiLGNBQWM7QUFDZCxNQUFNLEtBQUssR0FBRyxJQUFBLGVBQUssRUFBQyxRQUFRLENBQUMsQ0FBQztBQUU5QixjQUFjO0FBQ2QsTUFBTSw0QkFBNEIsR0FBRyxJQUFJLCtCQUFpQixFQUFFLENBQUM7QUFFN0QsY0FBYztBQUNkLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxxQkFBVSxDQUFDLFNBQVMsQ0FBQztJQUNsRCxJQUFJLEVBQUUsNkJBQTZCO0lBQ25DLElBQUksRUFBRSxtQ0FBbUM7SUFDekMsVUFBVSxFQUFFLENBQUMsVUFBVSxDQUFDO0NBQ3pCLENBQUMsQ0FBQztBQUNILGNBQWM7QUFDZCxNQUFNLG1CQUFtQixHQUFHLElBQUkscUJBQVUsQ0FBQyxTQUFTLENBQUM7SUFDbkQsSUFBSSxFQUFFLDhCQUE4QjtJQUNwQyxJQUFJLEVBQUUsMERBQTBEO0NBQ2pFLENBQUMsQ0FBQztBQUNILGNBQWM7QUFDZCxNQUFNLHFCQUFxQixHQUFHLElBQUkscUJBQVUsQ0FBQyxTQUFTLENBQUM7SUFDckQsSUFBSSxFQUFFLGdDQUFnQztJQUN0QyxJQUFJLEVBQUUscUNBQXFDO0NBQzVDLENBQUMsQ0FBQztBQUNILGNBQWM7QUFDZCxNQUFNLG9CQUFvQixHQUFHLElBQUkscUJBQVUsQ0FBQyxTQUFTLENBQUM7SUFDcEQs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
|