@naturalcycles/datastore-lib 3.17.1 → 3.18.2

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.
@@ -36,7 +36,12 @@ class DatastoreDB extends db_lib_1.BaseCommonDB {
36
36
  const DS = datastoreLib.Datastore;
37
37
  (_a = this.cfg).projectId || (_a.projectId = this.cfg.credentials?.project_id || process.env['GOOGLE_CLOUD_PROJECT']);
38
38
  (0, js_lib_1._assert)(this.cfg.projectId, '"projectId" is not set for DatastoreDB');
39
- this.cfg.logger.log(`DatastoreDB connected to ${(0, colors_1.boldWhite)(this.cfg.projectId)}`);
39
+ if (this.cfg.projectId) {
40
+ this.cfg.logger.log(`DatastoreDB connected to ${(0, colors_1.boldWhite)(this.cfg.projectId)}`);
41
+ }
42
+ else if (process.env['GOOGLE_APPLICATION_CREDENTIALS']) {
43
+ this.cfg.logger.log(`DatastoreDB connected via GOOGLE_APPLICATION_CREDENTIALS`);
44
+ }
40
45
  if (this.cfg.useLegacyGRPC) {
41
46
  this.cfg.grpc = require('grpc');
42
47
  }
@@ -55,9 +60,29 @@ class DatastoreDB extends db_lib_1.BaseCommonDB {
55
60
  if (!ids.length)
56
61
  return [];
57
62
  const keys = ids.map(id => this.key(table, id));
58
- const [entities] = await this.ds().get(keys);
59
- return (entities
60
- .map(e => this.mapId(e))
63
+ let rows;
64
+ try {
65
+ if (this.cfg.timeout) {
66
+ const r = await (0, js_lib_1.pTimeout)(this.ds().get(keys), {
67
+ timeout: this.cfg.timeout,
68
+ name: `datastore.getByIds(${table})`,
69
+ });
70
+ rows = r[0];
71
+ }
72
+ else {
73
+ rows = (await this.ds().get(keys))[0];
74
+ }
75
+ }
76
+ catch (err) {
77
+ this.cfg.logger.log('datastore recreated on error');
78
+ // This is to debug "GCP Datastore Timeout issue"
79
+ const datastoreLib = require('@google-cloud/datastore');
80
+ const DS = datastoreLib.Datastore;
81
+ this.cachedDatastore = new DS(this.cfg);
82
+ throw err;
83
+ }
84
+ return (rows
85
+ .map(r => this.mapId(r))
61
86
  // Seems like datastore .get() method doesn't return items properly sorted by input ids, so we gonna sort them here
62
87
  // same ids are not expected here
63
88
  .sort((a, b) => (a.id > b.id ? 1 : -1)));
@@ -34,6 +34,13 @@ export interface DatastoreDBCfg extends DatastoreOptions {
34
34
  * Default to `console`
35
35
  */
36
36
  logger?: CommonLogger;
37
+ /**
38
+ * Experimental option, currently only applies to `getByIds`.
39
+ * Applies pTimeout to Datastore operation, re-creates Datastore on any error.
40
+ *
41
+ * @experimental
42
+ */
43
+ timeout?: number;
37
44
  }
38
45
  export interface DatastoreCredentials {
39
46
  type?: string;
@@ -17,4 +17,5 @@ export declare class DatastoreKeyValueDB implements CommonKeyValueDB {
17
17
  streamIds(table: string, limit?: number): ReadableTyped<string>;
18
18
  streamValues(table: string, limit?: number): ReadableTyped<Buffer>;
19
19
  streamEntries(table: string, limit?: number): ReadableTyped<KeyValueDBTuple>;
20
+ count(_table: string): Promise<number>;
20
21
  }
@@ -47,5 +47,9 @@ class DatastoreKeyValueDB {
47
47
  errorMode: js_lib_1.ErrorMode.SUPPRESS, // cause .pipe() cannot propagate errors
48
48
  }));
49
49
  }
50
+ async count(_table) {
51
+ this.db.cfg.logger.warn(`DatastoreKeyValueDB.count is not supported`);
52
+ return 0;
53
+ }
50
54
  }
51
55
  exports.DatastoreKeyValueDB = DatastoreKeyValueDB;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/datastore-lib",
3
- "version": "3.17.1",
3
+ "version": "3.18.2",
4
4
  "description": "Opinionated library to work with Google Datastore",
5
5
  "scripts": {
6
6
  "prepare": "husky install"
@@ -17,7 +17,7 @@
17
17
  "devDependencies": {
18
18
  "@google-cloud/datastore": "^6.0.0",
19
19
  "@naturalcycles/dev-lib": "^12.0.1",
20
- "@types/node": "^16.0.0",
20
+ "@types/node": "^17.0.8",
21
21
  "jest": "^27.0.4"
22
22
  },
23
23
  "files": [
@@ -24,6 +24,7 @@ import {
24
24
  JsonSchemaRootObject,
25
25
  CommonLogger,
26
26
  commonLoggerMinLevel,
27
+ pTimeout,
27
28
  } from '@naturalcycles/js-lib'
28
29
  import { ReadableTyped } from '@naturalcycles/nodejs-lib'
29
30
  import { boldWhite } from '@naturalcycles/nodejs-lib/dist/colors'
@@ -85,7 +86,11 @@ export class DatastoreDB extends BaseCommonDB implements CommonDB {
85
86
 
86
87
  _assert(this.cfg.projectId, '"projectId" is not set for DatastoreDB')
87
88
 
88
- this.cfg.logger.log(`DatastoreDB connected to ${boldWhite(this.cfg.projectId)}`)
89
+ if (this.cfg.projectId) {
90
+ this.cfg.logger.log(`DatastoreDB connected to ${boldWhite(this.cfg.projectId)}`)
91
+ } else if (process.env['GOOGLE_APPLICATION_CREDENTIALS']) {
92
+ this.cfg.logger.log(`DatastoreDB connected via GOOGLE_APPLICATION_CREDENTIALS`)
93
+ }
89
94
 
90
95
  if (this.cfg.useLegacyGRPC) {
91
96
  this.cfg.grpc = require('grpc')
@@ -113,11 +118,32 @@ export class DatastoreDB extends BaseCommonDB implements CommonDB {
113
118
  ): Promise<ROW[]> {
114
119
  if (!ids.length) return []
115
120
  const keys = ids.map(id => this.key(table, id))
116
- const [entities] = await this.ds().get(keys)
121
+ let rows: any[]
122
+
123
+ try {
124
+ if (this.cfg.timeout) {
125
+ const r = await pTimeout(this.ds().get(keys), {
126
+ timeout: this.cfg.timeout,
127
+ name: `datastore.getByIds(${table})`,
128
+ })
129
+ rows = r[0]
130
+ } else {
131
+ rows = (await this.ds().get(keys))[0]
132
+ }
133
+ } catch (err) {
134
+ this.cfg.logger.log('datastore recreated on error')
135
+
136
+ // This is to debug "GCP Datastore Timeout issue"
137
+ const datastoreLib = require('@google-cloud/datastore')
138
+ const DS = datastoreLib.Datastore as typeof Datastore
139
+ this.cachedDatastore = new DS(this.cfg)
140
+
141
+ throw err
142
+ }
117
143
 
118
144
  return (
119
- (entities as any[])
120
- .map(e => this.mapId<ROW>(e))
145
+ rows
146
+ .map(r => this.mapId<ROW>(r))
121
147
  // Seems like datastore .get() method doesn't return items properly sorted by input ids, so we gonna sort them here
122
148
  // same ids are not expected here
123
149
  .sort((a, b) => (a.id > b.id ? 1 : -1))
@@ -41,6 +41,14 @@ export interface DatastoreDBCfg extends DatastoreOptions {
41
41
  * Default to `console`
42
42
  */
43
43
  logger?: CommonLogger
44
+
45
+ /**
46
+ * Experimental option, currently only applies to `getByIds`.
47
+ * Applies pTimeout to Datastore operation, re-creates Datastore on any error.
48
+ *
49
+ * @experimental
50
+ */
51
+ timeout?: number
44
52
  }
45
53
 
46
54
  export interface DatastoreCredentials {
@@ -76,4 +76,9 @@ export class DatastoreKeyValueDB implements CommonKeyValueDB {
76
76
  }),
77
77
  )
78
78
  }
79
+
80
+ async count(_table: string): Promise<number> {
81
+ this.db.cfg.logger.warn(`DatastoreKeyValueDB.count is not supported`)
82
+ return 0
83
+ }
79
84
  }