@autofleet/settings 1.1.3 → 1.2.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/index.d.ts CHANGED
@@ -10,6 +10,7 @@ interface Label {
10
10
  businessModelId?: string;
11
11
  demandSourceId?: string;
12
12
  fleetId?: string;
13
+ time?: string | Date;
13
14
  }
14
15
  declare type LabelsArray = Label[];
15
16
  interface GetSettingOption {
@@ -32,5 +33,6 @@ declare class SettingsManager {
32
33
  }[], labels: LabelsArray, { timeout, rejectOnFail }?: GetSettingOption): Promise<any>;
33
34
  setLocal(key: string, labels: LabelsArray, value: SettingValue): void;
34
35
  flush(): void;
36
+ getCacheKey(key: SettingValue, labels: LabelsArray): string;
35
37
  }
36
38
  export default SettingsManager;
package/dist/index.js CHANGED
@@ -21,6 +21,7 @@ const logger_1 = __importDefault(require("@autofleet/logger"));
21
21
  const node_cache_1 = __importDefault(require("node-cache"));
22
22
  const events_1 = __importDefault(require("events"));
23
23
  const util_1 = __importDefault(require("util"));
24
+ const moment_1 = __importDefault(require("moment"));
24
25
  dotenv_1.default.config();
25
26
  const nextTick = util_1.default.promisify(process.nextTick);
26
27
  const logger = logger_1.default();
@@ -57,13 +58,16 @@ class SettingsManager {
57
58
  if (typeof defaultValue === 'undefined') {
58
59
  throw new Error('Can\'t get a key without defaultValue');
59
60
  }
60
- const cacheKey = `${key}_${JSON.stringify(labels)}`;
61
+ const cacheKey = this.getCacheKey(key, labels);
61
62
  const cacheValue = this.settingsCache.get(cacheKey);
62
63
  if (cacheValue !== undefined) {
63
64
  if (waitingToNetwork === cacheValue) {
64
65
  yield nextTick();
65
- return new Promise((resolve) => {
66
+ return new Promise((resolve, reject) => {
66
67
  this.networkEvents.once(cacheKey, (networkValue) => {
68
+ if (networkValue instanceof Error && rejectOnFail) {
69
+ return reject(networkValue);
70
+ }
67
71
  resolve(SettingsManager.readNetworkValue(networkValue, defaultValue));
68
72
  });
69
73
  });
@@ -87,7 +91,9 @@ class SettingsManager {
87
91
  catch (error) {
88
92
  logger.error('Cant get setting from network', { error });
89
93
  if (rejectOnFail) {
90
- throw new CannotGetNetworkValueError();
94
+ const errorToThrow = new CannotGetNetworkValueError();
95
+ this.networkEvents.emit(cacheKey, errorToThrow);
96
+ throw errorToThrow;
91
97
  }
92
98
  }
93
99
  this.networkEvents.emit(cacheKey, networkValue);
@@ -108,7 +114,7 @@ class SettingsManager {
108
114
  const settingsToReturn = new Map();
109
115
  const settingsToFetch = [];
110
116
  settingsToGet.map((obj) => {
111
- const cacheKey = `${obj.key}_${JSON.stringify(labels)}`;
117
+ const cacheKey = this.getCacheKey(obj.key, labels);
112
118
  const cacheValue = this.settingsCache.get(cacheKey);
113
119
  if (cacheValue) {
114
120
  settingsToReturn.set(obj.key, cacheValue);
@@ -144,7 +150,7 @@ class SettingsManager {
144
150
  }
145
151
  }
146
152
  return settingsToGet.map((setting) => {
147
- const cacheKey = `${setting.key}_${JSON.stringify(labels)}`;
153
+ const cacheKey = this.getCacheKey(setting.key, labels);
148
154
  let returnValue;
149
155
  try {
150
156
  returnValue = SettingsManager.readNetworkValue(settingsToReturn.get(setting.key), setting.defaultValue);
@@ -159,11 +165,22 @@ class SettingsManager {
159
165
  });
160
166
  }
161
167
  setLocal(key, labels, value) {
162
- const cacheKey = `${key}_${JSON.stringify(labels)}`;
168
+ const cacheKey = this.getCacheKey(key, labels);
163
169
  this.settingsCache.set(cacheKey, value, this.ttl);
164
170
  }
165
171
  flush() {
166
172
  return this.settingsCache.flushAll();
167
173
  }
174
+ // eslint-disable-next-line class-methods-use-this
175
+ getCacheKey(key, labels) {
176
+ const newLabels = labels.map((l) => {
177
+ if (l.time) {
178
+ return Object.assign(Object.assign({}, l), { time: moment_1.default(l.time).startOf('hour').format(), day: moment_1.default(l.time).day() });
179
+ }
180
+ return l;
181
+ });
182
+ const cacheKey = `${key}_${JSON.stringify(newLabels)}`;
183
+ return cacheKey;
184
+ }
168
185
  }
169
186
  exports.default = SettingsManager;
@@ -105,6 +105,18 @@ describe('Settings', () => {
105
105
  expect(value).toEqual('value1');
106
106
  expect(m.isDone()).toBeTruthy();
107
107
  }));
108
+ it('Finds with time label', () => __awaiter(void 0, void 0, void 0, function* () {
109
+ const time = new Date();
110
+ const labels = [{ fleetId: 'uuid', time }];
111
+ const m = mockSetting('key1', 'value1', labels);
112
+ const settings = new index_1.default({
113
+ serviceUrl: `http://${serviceUrl}/`,
114
+ });
115
+ const settingLabel = [{ fleetId: 'uuid', time }];
116
+ const value = yield settings.get('key1', 'dv', settingLabel);
117
+ expect(value).toEqual('value1');
118
+ expect(m.isDone()).toBeTruthy();
119
+ }));
108
120
  it('Returns default value when network error', () => __awaiter(void 0, void 0, void 0, function* () {
109
121
  const settings = new index_1.default({
110
122
  serviceUrl: `http://${serviceUrl}/`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autofleet/settings",
3
- "version": "1.1.3",
3
+ "version": "1.2.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -20,6 +20,7 @@
20
20
  "bluebird": "^3.7.2",
21
21
  "dotenv": "^8.2.0",
22
22
  "jest": "^22.4.4",
23
+ "moment": "^2.29.1",
23
24
  "nock": "^10.0.2",
24
25
  "node-cache": "^5.1.2"
25
26
  },
package/src/index.test.ts CHANGED
@@ -117,6 +117,20 @@ describe('Settings', () => {
117
117
  expect(m.isDone()).toBeTruthy();
118
118
  });
119
119
 
120
+ it('Finds with time label', async () => {
121
+ const time = new Date();
122
+ const labels = [{ fleetId: 'uuid', time }];
123
+ const m = mockSetting('key1', 'value1', labels);
124
+ const settings = new Settings({
125
+ serviceUrl: `http://${serviceUrl}/`,
126
+ });
127
+
128
+ const settingLabel = [{ fleetId: 'uuid', time }];
129
+ const value = await settings.get('key1', 'dv', settingLabel);
130
+ expect(value).toEqual('value1');
131
+ expect(m.isDone()).toBeTruthy();
132
+ });
133
+
120
134
  it('Returns default value when network error', async () => {
121
135
  const settings = new Settings({
122
136
  serviceUrl: `http://${serviceUrl}/`,
package/src/index.ts CHANGED
@@ -7,6 +7,7 @@ import Logger from '@autofleet/logger';
7
7
  import NodeCache from 'node-cache';
8
8
  import EventEmitter from 'events';
9
9
  import util from 'util';
10
+ import moment from 'moment';
10
11
 
11
12
  dotenv.config();
12
13
 
@@ -31,6 +32,7 @@ interface Label {
31
32
  businessModelId?: string;
32
33
  demandSourceId?: string;
33
34
  fleetId?: string;
35
+ time?: string | Date;
34
36
  }
35
37
 
36
38
  type LabelsArray = Label[];
@@ -90,13 +92,16 @@ class SettingsManager {
90
92
  throw new Error('Can\'t get a key without defaultValue');
91
93
  }
92
94
 
93
- const cacheKey = `${key}_${JSON.stringify(labels)}`;
95
+ const cacheKey = this.getCacheKey(key, labels);
94
96
  const cacheValue = this.settingsCache.get(cacheKey);
95
97
  if (cacheValue !== undefined) {
96
98
  if (waitingToNetwork === cacheValue) {
97
99
  await nextTick();
98
- return new Promise((resolve) => {
100
+ return new Promise((resolve, reject) => {
99
101
  this.networkEvents.once(cacheKey, (networkValue) => {
102
+ if (networkValue instanceof Error && rejectOnFail) {
103
+ return reject(networkValue);
104
+ }
100
105
  resolve(SettingsManager.readNetworkValue(networkValue, defaultValue));
101
106
  });
102
107
  });
@@ -121,7 +126,9 @@ class SettingsManager {
121
126
  } catch (error) {
122
127
  logger.error('Cant get setting from network', { error });
123
128
  if (rejectOnFail) {
124
- throw new CannotGetNetworkValueError();
129
+ const errorToThrow = new CannotGetNetworkValueError();
130
+ this.networkEvents.emit(cacheKey, errorToThrow);
131
+ throw errorToThrow;
125
132
  }
126
133
  }
127
134
 
@@ -149,7 +156,7 @@ class SettingsManager {
149
156
  const settingsToFetch: any[] = [];
150
157
 
151
158
  settingsToGet.map((obj) => {
152
- const cacheKey = `${obj.key}_${JSON.stringify(labels)}`;
159
+ const cacheKey = this.getCacheKey(obj.key, labels);
153
160
  const cacheValue = this.settingsCache.get(cacheKey);
154
161
  if (cacheValue) {
155
162
  settingsToReturn.set(obj.key, cacheValue);
@@ -187,7 +194,7 @@ class SettingsManager {
187
194
  }
188
195
 
189
196
  return settingsToGet.map((setting: any) => {
190
- const cacheKey = `${setting.key}_${JSON.stringify(labels)}`;
197
+ const cacheKey = this.getCacheKey(setting.key, labels);
191
198
  let returnValue;
192
199
  try {
193
200
  returnValue = SettingsManager.readNetworkValue(settingsToReturn.get(setting.key), setting.defaultValue);
@@ -201,13 +208,30 @@ class SettingsManager {
201
208
  }
202
209
 
203
210
  setLocal(key: string, labels: LabelsArray, value: SettingValue) {
204
- const cacheKey = `${key}_${JSON.stringify(labels)}`;
211
+ const cacheKey = this.getCacheKey(key, labels);
205
212
  this.settingsCache.set(cacheKey, value, this.ttl);
206
213
  }
207
214
 
208
215
  flush() {
209
216
  return this.settingsCache.flushAll();
210
217
  }
218
+
219
+ // eslint-disable-next-line class-methods-use-this
220
+ getCacheKey(key: SettingValue, labels: LabelsArray) {
221
+ const newLabels = labels.map((l) => {
222
+ if (l.time) {
223
+ return {
224
+ ...l,
225
+ time: moment(l.time).startOf('hour').format(),
226
+ day: moment(l.time).day(),
227
+ };
228
+ }
229
+ return l;
230
+ });
231
+
232
+ const cacheKey = `${key}_${JSON.stringify(newLabels)}`;
233
+ return cacheKey;
234
+ }
211
235
  }
212
236
 
213
237
  export default SettingsManager;