@cubejs-backend/query-orchestrator 0.23.3 → 0.24.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.
Files changed (96) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +2 -2
  3. package/dist/src/driver/BaseDriver.d.ts +36 -0
  4. package/dist/src/driver/BaseDriver.d.ts.map +1 -0
  5. package/dist/src/driver/BaseDriver.js +175 -0
  6. package/dist/src/driver/BaseDriver.js.map +1 -0
  7. package/dist/src/driver/index.d.ts +3 -0
  8. package/dist/src/driver/index.d.ts.map +1 -0
  9. package/dist/src/driver/index.js +15 -0
  10. package/dist/src/driver/index.js.map +1 -0
  11. package/dist/src/driver/utils.d.ts +2 -0
  12. package/dist/src/driver/utils.d.ts.map +1 -0
  13. package/dist/src/driver/utils.js +17 -0
  14. package/dist/src/driver/utils.js.map +1 -0
  15. package/dist/src/index.d.ts +3 -0
  16. package/dist/src/index.d.ts.map +1 -0
  17. package/dist/src/index.js +15 -0
  18. package/dist/src/index.js.map +1 -0
  19. package/dist/src/orchestrator/BaseQueueDriver.d.ts +4 -0
  20. package/dist/src/orchestrator/BaseQueueDriver.d.ts.map +1 -0
  21. package/dist/src/orchestrator/BaseQueueDriver.js +16 -0
  22. package/dist/src/orchestrator/BaseQueueDriver.js.map +1 -0
  23. package/dist/src/orchestrator/ContinueWaitError.d.ts +3 -0
  24. package/dist/src/orchestrator/ContinueWaitError.d.ts.map +1 -0
  25. package/dist/src/orchestrator/ContinueWaitError.js +10 -0
  26. package/dist/src/orchestrator/ContinueWaitError.js.map +1 -0
  27. package/dist/src/orchestrator/LocalCacheDriver.d.ts +8 -0
  28. package/dist/src/orchestrator/LocalCacheDriver.d.ts.map +1 -0
  29. package/dist/src/orchestrator/LocalCacheDriver.js +30 -0
  30. package/dist/src/orchestrator/LocalCacheDriver.js.map +1 -0
  31. package/dist/src/orchestrator/LocalQueueDriver.d.ts +57 -0
  32. package/dist/src/orchestrator/LocalQueueDriver.d.ts.map +1 -0
  33. package/dist/src/orchestrator/LocalQueueDriver.js +230 -0
  34. package/dist/src/orchestrator/LocalQueueDriver.js.map +1 -0
  35. package/dist/src/orchestrator/PreAggregations.d.ts +26 -0
  36. package/dist/src/orchestrator/PreAggregations.d.ts.map +1 -0
  37. package/dist/src/orchestrator/PreAggregations.js +565 -0
  38. package/dist/src/orchestrator/PreAggregations.js.map +1 -0
  39. package/dist/src/orchestrator/QueryCache.d.ts +51 -0
  40. package/dist/src/orchestrator/QueryCache.d.ts.map +1 -0
  41. package/dist/src/orchestrator/QueryCache.js +293 -0
  42. package/dist/src/orchestrator/QueryCache.js.map +1 -0
  43. package/dist/src/orchestrator/QueryOrchestrator.d.ts +27 -0
  44. package/dist/src/orchestrator/QueryOrchestrator.d.ts.map +1 -0
  45. package/dist/src/orchestrator/QueryOrchestrator.js +79 -0
  46. package/dist/src/orchestrator/QueryOrchestrator.js.map +1 -0
  47. package/dist/src/orchestrator/QueryQueue.d.ts +36 -0
  48. package/dist/src/orchestrator/QueryQueue.d.ts.map +1 -0
  49. package/dist/src/orchestrator/QueryQueue.js +351 -0
  50. package/dist/src/orchestrator/QueryQueue.js.map +1 -0
  51. package/dist/src/orchestrator/RedisCacheDriver.d.ts +12 -0
  52. package/dist/src/orchestrator/RedisCacheDriver.d.ts.map +1 -0
  53. package/dist/src/orchestrator/RedisCacheDriver.js +50 -0
  54. package/dist/src/orchestrator/RedisCacheDriver.js.map +1 -0
  55. package/dist/src/orchestrator/RedisFactory.d.ts +3 -0
  56. package/dist/src/orchestrator/RedisFactory.d.ts.map +1 -0
  57. package/dist/src/orchestrator/RedisFactory.js +45 -0
  58. package/dist/src/orchestrator/RedisFactory.js.map +1 -0
  59. package/dist/src/orchestrator/RedisPool.d.ts +10 -0
  60. package/dist/src/orchestrator/RedisPool.d.ts.map +1 -0
  61. package/dist/src/orchestrator/RedisPool.js +57 -0
  62. package/dist/src/orchestrator/RedisPool.js.map +1 -0
  63. package/dist/src/orchestrator/RedisQueueDriver.d.ts +47 -0
  64. package/dist/src/orchestrator/RedisQueueDriver.d.ts.map +1 -0
  65. package/dist/src/orchestrator/RedisQueueDriver.js +253 -0
  66. package/dist/src/orchestrator/RedisQueueDriver.js.map +1 -0
  67. package/dist/src/orchestrator/TimeoutError.d.ts +4 -0
  68. package/dist/src/orchestrator/TimeoutError.d.ts.map +1 -0
  69. package/dist/src/orchestrator/TimeoutError.js +7 -0
  70. package/dist/src/orchestrator/TimeoutError.js.map +1 -0
  71. package/dist/src/orchestrator/index.d.ts +14 -0
  72. package/dist/src/orchestrator/index.d.ts.map +1 -0
  73. package/dist/src/orchestrator/index.js +26 -0
  74. package/dist/src/orchestrator/index.js.map +1 -0
  75. package/driver/BaseDriver.js +5 -221
  76. package/driver/README.md +3 -0
  77. package/driver/utils.js +8 -12
  78. package/orchestrator/BaseQueueDriver.js +5 -8
  79. package/orchestrator/ContinueWaitError.js +6 -5
  80. package/orchestrator/LocalCacheDriver.js +5 -29
  81. package/orchestrator/LocalQueueDriver.js +5 -256
  82. package/orchestrator/PreAggregations.js +4 -764
  83. package/orchestrator/QueryCache.js +5 -381
  84. package/orchestrator/QueryOrchestrator.js +5 -100
  85. package/orchestrator/QueryQueue.js +5 -378
  86. package/orchestrator/README.md +3 -0
  87. package/orchestrator/RedisCacheDriver.js +5 -45
  88. package/orchestrator/RedisFactory.js +6 -46
  89. package/orchestrator/RedisPool.js +5 -49
  90. package/orchestrator/RedisQueueDriver.js +5 -283
  91. package/orchestrator/TimeoutError.js +6 -1
  92. package/package.json +29 -10
  93. package/test/integration/PreAggregations.test.js +0 -337
  94. package/test/integration/QueryQueueRedis.test.js +0 -6
  95. package/test/unit/QueryOrchestrator.test.js +0 -301
  96. package/test/unit/QueryQueue.test.js +0 -249
@@ -0,0 +1,351 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.QueryQueue = void 0;
7
+ const ramda_1 = __importDefault(require("ramda"));
8
+ const TimeoutError_1 = require("./TimeoutError");
9
+ const ContinueWaitError_1 = require("./ContinueWaitError");
10
+ const RedisQueueDriver_1 = require("./RedisQueueDriver");
11
+ const LocalQueueDriver_1 = require("./LocalQueueDriver");
12
+ class QueryQueue {
13
+ constructor(redisQueuePrefix, options) {
14
+ this.redisQueuePrefix = redisQueuePrefix;
15
+ this.concurrency = options.concurrency || 2;
16
+ this.continueWaitTimeout = options.continueWaitTimeout || 5;
17
+ this.executionTimeout = options.executionTimeout || 600;
18
+ this.orphanedTimeout = options.orphanedTimeout || 120;
19
+ this.heartBeatInterval = options.heartBeatInterval || 30;
20
+ this.sendProcessMessageFn = options.sendProcessMessageFn || ((queryKey) => { this.processQuery(queryKey); });
21
+ this.sendCancelMessageFn = options.sendCancelMessageFn || ((query) => { this.processCancel(query); });
22
+ this.queryHandlers = options.queryHandlers;
23
+ this.cancelHandlers = options.cancelHandlers;
24
+ this.logger = options.logger || ((message, event) => console.log(`${message} ${JSON.stringify(event)}`));
25
+ const queueDriverOptions = {
26
+ redisQueuePrefix: this.redisQueuePrefix,
27
+ concurrency: this.concurrency,
28
+ continueWaitTimeout: this.continueWaitTimeout,
29
+ orphanedTimeout: this.orphanedTimeout,
30
+ heartBeatTimeout: this.heartBeatInterval * 4,
31
+ redisPool: options.redisPool
32
+ };
33
+ this.queueDriver = options.cacheAndQueueDriver === 'redis' ?
34
+ new RedisQueueDriver_1.RedisQueueDriver(queueDriverOptions) :
35
+ new LocalQueueDriver_1.LocalQueueDriver(queueDriverOptions);
36
+ }
37
+ async executeInQueue(queryHandler, queryKey, query, priority, options) {
38
+ options = options || {};
39
+ const redisClient = await this.queueDriver.createConnection();
40
+ try {
41
+ if (priority == null) {
42
+ priority = 0;
43
+ }
44
+ if (!(priority >= -10000 && priority <= 10000)) {
45
+ throw new Error('Priority should be between -10000 and 10000');
46
+ }
47
+ let result = await redisClient.getResult(queryKey);
48
+ if (result) {
49
+ return this.parseResult(result);
50
+ }
51
+ const time = new Date().getTime();
52
+ const keyScore = time + (10000 - priority) * 1E14;
53
+ // eslint-disable-next-line no-unused-vars
54
+ const [added, b, c, queueSize] = await redisClient.addToQueue(keyScore, queryKey, time, queryHandler, query, priority, options);
55
+ if (added > 0) {
56
+ this.logger('Added to queue', {
57
+ priority,
58
+ queueSize,
59
+ queryKey,
60
+ queuePrefix: this.redisQueuePrefix,
61
+ requestId: options.requestId,
62
+ });
63
+ }
64
+ await this.reconcileQueue();
65
+ const queryDef = await redisClient.getQueryDef(queryKey);
66
+ const [active, toProcess] = await redisClient.getQueryStageState(true);
67
+ if (queryDef) {
68
+ this.logger('Waiting for query', {
69
+ queueSize,
70
+ queryKey: queryDef.queryKey,
71
+ queuePrefix: this.redisQueuePrefix,
72
+ requestId: options.requestId,
73
+ activeQueryKeys: active,
74
+ toProcessQueryKeys: toProcess,
75
+ active: active.indexOf(redisClient.redisHash(queryKey)) !== -1,
76
+ queueIndex: toProcess.indexOf(redisClient.redisHash(queryKey)),
77
+ waitingForRequestId: queryDef.requestId
78
+ });
79
+ }
80
+ result = await redisClient.getResultBlocking(queryKey);
81
+ if (!result) {
82
+ throw new ContinueWaitError_1.ContinueWaitError();
83
+ }
84
+ return this.parseResult(result);
85
+ }
86
+ finally {
87
+ this.queueDriver.release(redisClient);
88
+ }
89
+ }
90
+ parseResult(result) {
91
+ if (!result) {
92
+ return;
93
+ }
94
+ if (result.error) {
95
+ throw new Error(result.error); // TODO
96
+ }
97
+ else {
98
+ // eslint-disable-next-line consistent-return
99
+ return result.result;
100
+ }
101
+ }
102
+ async reconcileQueue() {
103
+ if (!this.reconcilePromise) {
104
+ this.reconcileAgain = false;
105
+ this.reconcilePromise = this.reconcileQueueImpl().then(() => {
106
+ this.reconcilePromise = null;
107
+ if (this.reconcileAgain) {
108
+ return this.reconcileQueue();
109
+ }
110
+ return null;
111
+ });
112
+ }
113
+ else {
114
+ this.reconcileAgain = true;
115
+ }
116
+ return this.reconcilePromise;
117
+ }
118
+ async reconcileQueueImpl() {
119
+ const redisClient = await this.queueDriver.createConnection();
120
+ try {
121
+ const toCancel = (await redisClient.getStalledQueries()).concat(await redisClient.getOrphanedQueries());
122
+ await Promise.all(toCancel.map(async (queryKey) => {
123
+ const [query] = await redisClient.getQueryAndRemove(queryKey);
124
+ if (query) {
125
+ this.logger('Removing orphaned query', {
126
+ queryKey: query.queryKey,
127
+ queuePrefix: this.redisQueuePrefix,
128
+ requestId: query.requestId
129
+ });
130
+ await this.sendCancelMessageFn(query);
131
+ }
132
+ }));
133
+ const active = await redisClient.getActiveQueries();
134
+ const toProcess = await redisClient.getToProcessQueries();
135
+ await Promise.all(ramda_1.default.pipe(ramda_1.default.filter(p => active.indexOf(p) === -1), ramda_1.default.take(this.concurrency), ramda_1.default.map(this.sendProcessMessageFn))(toProcess));
136
+ }
137
+ finally {
138
+ this.queueDriver.release(redisClient);
139
+ }
140
+ }
141
+ queryTimeout(promise) {
142
+ let timeout;
143
+ const { executionTimeout } = this;
144
+ return Promise.race([
145
+ promise,
146
+ new Promise((resolve, reject) => {
147
+ timeout = setTimeout(() => {
148
+ reject(new TimeoutError_1.TimeoutError(`Query execution timeout after ${executionTimeout / 60} min of waiting`));
149
+ }, executionTimeout * 1000);
150
+ }),
151
+ ]).then((v) => {
152
+ clearTimeout(timeout);
153
+ return v;
154
+ }, (err) => {
155
+ clearTimeout(timeout);
156
+ throw err;
157
+ });
158
+ }
159
+ async fetchQueryStageState() {
160
+ const redisClient = await this.queueDriver.createConnection();
161
+ try {
162
+ return redisClient.getQueryStageState();
163
+ }
164
+ finally {
165
+ this.queueDriver.release(redisClient);
166
+ }
167
+ }
168
+ async getQueryStage(stageQueryKey, priorityFilter, queryStageState) {
169
+ const [active, toProcess, allQueryDefs] = queryStageState || await this.fetchQueryStageState();
170
+ const queryDefs = toProcess.map(k => allQueryDefs[k]).filter(q => !!q);
171
+ const queryInQueue = queryDefs.find(q => this.redisHash(q.stageQueryKey) === this.redisHash(stageQueryKey) &&
172
+ (priorityFilter != null ? q.priority === priorityFilter : true));
173
+ if (queryInQueue) {
174
+ if (active.indexOf(this.redisHash(queryInQueue.queryKey)) !== -1) {
175
+ return {
176
+ stage: 'Executing query',
177
+ timeElapsed: queryInQueue.startQueryTime ? new Date().getTime() - queryInQueue.startQueryTime : undefined
178
+ };
179
+ }
180
+ const index = queryDefs.filter(q => active.indexOf(this.redisHash(q.queryKey)) === -1).indexOf(queryInQueue);
181
+ if (index !== -1) {
182
+ return index !== -1 ? { stage: `#${index + 1} in queue` } : undefined;
183
+ }
184
+ }
185
+ return undefined;
186
+ }
187
+ async processQuery(queryKey) {
188
+ const redisClient = await this.queueDriver.createConnection();
189
+ let insertedCount;
190
+ // eslint-disable-next-line no-unused-vars
191
+ let removedCount;
192
+ let activeKeys;
193
+ let queueSize;
194
+ let query;
195
+ let processingLockAcquired;
196
+ try {
197
+ const processingId = await redisClient.getNextProcessingId();
198
+ const retrieveResult = await redisClient.retrieveForProcessing(queryKey, processingId);
199
+ if (retrieveResult) {
200
+ [insertedCount, removedCount, activeKeys, queueSize, query, processingLockAcquired] = retrieveResult;
201
+ }
202
+ const activated = activeKeys && activeKeys.indexOf(this.redisHash(queryKey)) !== -1;
203
+ if (!query) {
204
+ query = await redisClient.getQueryDef(this.redisHash(queryKey));
205
+ }
206
+ if (query && insertedCount && activated && processingLockAcquired) {
207
+ let executionResult;
208
+ const startQueryTime = (new Date()).getTime();
209
+ const timeInQueue = (new Date()).getTime() - query.addedToQueueTime;
210
+ this.logger('Performing query', {
211
+ processingId,
212
+ queueSize,
213
+ queryKey: query.queryKey,
214
+ queuePrefix: this.redisQueuePrefix,
215
+ requestId: query.requestId,
216
+ timeInQueue
217
+ });
218
+ await redisClient.optimisticQueryUpdate(queryKey, { startQueryTime }, processingId);
219
+ const heartBeatTimer = setInterval(() => redisClient.updateHeartBeat(queryKey), this.heartBeatInterval * 1000);
220
+ try {
221
+ executionResult = {
222
+ result: await this.queryTimeout(this.queryHandlers[query.queryHandler](query.query, async (cancelHandler) => {
223
+ try {
224
+ return redisClient.optimisticQueryUpdate(queryKey, { cancelHandler }, processingId);
225
+ }
226
+ catch (e) {
227
+ this.logger('Error while query update', {
228
+ queryKey: query.queryKey,
229
+ error: e.stack || e,
230
+ queuePrefix: this.redisQueuePrefix,
231
+ requestId: query.requestId
232
+ });
233
+ }
234
+ return null;
235
+ }))
236
+ };
237
+ this.logger('Performing query completed', {
238
+ processingId,
239
+ queueSize,
240
+ duration: ((new Date()).getTime() - startQueryTime),
241
+ queryKey: query.queryKey,
242
+ queuePrefix: this.redisQueuePrefix,
243
+ requestId: query.requestId,
244
+ timeInQueue
245
+ });
246
+ }
247
+ catch (e) {
248
+ executionResult = {
249
+ error: (e.message || e).toString() // TODO error handling
250
+ };
251
+ this.logger('Error while querying', {
252
+ processingId,
253
+ queueSize,
254
+ duration: ((new Date()).getTime() - startQueryTime),
255
+ queryKey: query.queryKey,
256
+ queuePrefix: this.redisQueuePrefix,
257
+ requestId: query.requestId,
258
+ timeInQueue,
259
+ error: (e.stack || e).toString()
260
+ });
261
+ if (e instanceof TimeoutError_1.TimeoutError) {
262
+ const queryWithCancelHandle = await redisClient.getQueryDef(queryKey);
263
+ if (queryWithCancelHandle) {
264
+ this.logger('Cancelling query due to timeout', {
265
+ processingId,
266
+ queryKey: queryWithCancelHandle.queryKey,
267
+ queuePrefix: this.redisQueuePrefix,
268
+ requestId: queryWithCancelHandle.requestId
269
+ });
270
+ await this.sendCancelMessageFn(queryWithCancelHandle);
271
+ }
272
+ }
273
+ }
274
+ clearInterval(heartBeatTimer);
275
+ if (!(await redisClient.setResultAndRemoveQuery(queryKey, executionResult, processingId))) {
276
+ this.logger('Orphaned execution result', {
277
+ processingId,
278
+ warn: 'Result for query was not set due to processing lock wasn\'t acquired',
279
+ queryKey: query.queryKey,
280
+ queuePrefix: this.redisQueuePrefix,
281
+ requestId: query.requestId
282
+ });
283
+ }
284
+ await this.reconcileQueue();
285
+ }
286
+ else {
287
+ this.logger('Skip processing', {
288
+ processingId,
289
+ queryKey: query && query.queryKey || queryKey,
290
+ requestId: query && query.requestId,
291
+ queuePrefix: this.redisQueuePrefix,
292
+ processingLockAcquired,
293
+ query,
294
+ insertedCount,
295
+ activeKeys,
296
+ activated,
297
+ queryExists: !!query
298
+ });
299
+ const currentProcessingId = await redisClient.freeProcessingLock(queryKey, processingId, activated);
300
+ if (currentProcessingId) {
301
+ this.logger('Skipping free processing lock', {
302
+ processingId,
303
+ currentProcessingId,
304
+ queryKey: query && query.queryKey || queryKey,
305
+ requestId: query && query.requestId,
306
+ queuePrefix: this.redisQueuePrefix,
307
+ processingLockAcquired,
308
+ query,
309
+ insertedCount,
310
+ activeKeys,
311
+ activated,
312
+ queryExists: !!query
313
+ });
314
+ }
315
+ }
316
+ }
317
+ catch (e) {
318
+ this.logger('Queue storage error', {
319
+ queryKey: query && query.queryKey || queryKey,
320
+ requestId: query && query.requestId,
321
+ error: (e.stack || e).toString(),
322
+ queuePrefix: this.redisQueuePrefix
323
+ });
324
+ }
325
+ finally {
326
+ this.queueDriver.release(redisClient);
327
+ }
328
+ }
329
+ async processCancel(query) {
330
+ const { queryHandler } = query;
331
+ try {
332
+ if (!this.cancelHandlers[queryHandler]) {
333
+ throw new Error(`No cancel handler for ${queryHandler}`);
334
+ }
335
+ await this.cancelHandlers[queryHandler](query);
336
+ }
337
+ catch (e) {
338
+ this.logger('Error while cancel', {
339
+ queryKey: query.queryKey,
340
+ error: e.stack || e,
341
+ queuePrefix: this.redisQueuePrefix,
342
+ requestId: query.requestId
343
+ });
344
+ }
345
+ }
346
+ redisHash(queryKey) {
347
+ return this.queueDriver.redisHash(queryKey);
348
+ }
349
+ }
350
+ exports.QueryQueue = QueryQueue;
351
+ //# sourceMappingURL=QueryQueue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryQueue.js","sourceRoot":"","sources":["../../../src/orchestrator/QueryQueue.js"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export class RedisCacheDriver {
2
+ constructor({ pool }: {
3
+ pool: any;
4
+ });
5
+ redisPool: any;
6
+ getClient(): Promise<any>;
7
+ get(key: any): Promise<any>;
8
+ set(key: any, value: any, expiration: any): Promise<any>;
9
+ remove(key: any): Promise<any>;
10
+ keysStartingWith(prefix: any): Promise<any>;
11
+ }
12
+ //# sourceMappingURL=RedisCacheDriver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RedisCacheDriver.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/RedisCacheDriver.js"],"names":[],"mappings":"AAAA;IACE;;OAEC;IADC,eAAqB;IAGvB,0BAEC;IAED,4BAQC;IAED,yDAOC;IAED,+BAOC;IAED,4CAOC;CACF"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RedisCacheDriver = void 0;
4
+ class RedisCacheDriver {
5
+ constructor({ pool }) {
6
+ this.redisPool = pool;
7
+ }
8
+ async getClient() {
9
+ return this.redisPool.getClient();
10
+ }
11
+ async get(key) {
12
+ const client = await this.getClient();
13
+ try {
14
+ const res = await client.getAsync(key);
15
+ return res && JSON.parse(res);
16
+ }
17
+ finally {
18
+ this.redisPool.release(client);
19
+ }
20
+ }
21
+ async set(key, value, expiration) {
22
+ const client = await this.getClient();
23
+ try {
24
+ return await client.setAsync(key, JSON.stringify(value), 'EX', expiration);
25
+ }
26
+ finally {
27
+ this.redisPool.release(client);
28
+ }
29
+ }
30
+ async remove(key) {
31
+ const client = await this.getClient();
32
+ try {
33
+ return await client.delAsync(key);
34
+ }
35
+ finally {
36
+ this.redisPool.release(client);
37
+ }
38
+ }
39
+ async keysStartingWith(prefix) {
40
+ const client = await this.getClient();
41
+ try {
42
+ return await client.keysAsync(`${prefix}*`);
43
+ }
44
+ finally {
45
+ this.redisPool.release(client);
46
+ }
47
+ }
48
+ }
49
+ exports.RedisCacheDriver = RedisCacheDriver;
50
+ //# sourceMappingURL=RedisCacheDriver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RedisCacheDriver.js","sourceRoot":"","sources":["../../../src/orchestrator/RedisCacheDriver.js"],"names":[],"mappings":";;;AAAA,MAAa,gBAAgB;IAC3B,YAAY,EAAE,IAAI,EAAE;QAClB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,SAAS;QACb,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAG;QACX,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACtC,IAAI;YACF,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YACvC,OAAO,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;SAC/B;gBAAS;YACR,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;SAChC;IACH,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,UAAU;QAC9B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACtC,IAAI;YACF,OAAO,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;SAC5E;gBAAS;YACR,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;SAChC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAG;QACd,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACtC,IAAI;YACF,OAAO,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;SACnC;gBAAS;YACR,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;SAChC;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,MAAM;QAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACtC,IAAI;YACF,OAAO,MAAM,MAAM,CAAC,SAAS,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC;SAC7C;gBAAS;YACR,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;SAChC;IACH,CAAC;CACF;AA7CD,4CA6CC"}
@@ -0,0 +1,3 @@
1
+ export function createRedisClient(url: any): redis.RedisClient;
2
+ import redis from "redis";
3
+ //# sourceMappingURL=RedisFactory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RedisFactory.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/RedisFactory.js"],"names":[],"mappings":"AAGA,+DA4CC"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createRedisClient = void 0;
7
+ const redis_1 = __importDefault(require("redis"));
8
+ const util_1 = require("util");
9
+ function createRedisClient(url) {
10
+ redis_1.default.Multi.prototype.execAsync = function execAsync() {
11
+ return new Promise((resolve, reject) => this.exec((err, res) => (err ? reject(err) : resolve(res))));
12
+ };
13
+ const options = {
14
+ url,
15
+ };
16
+ if (process.env.REDIS_TLS === 'true') {
17
+ options.tls = {};
18
+ }
19
+ if (process.env.REDIS_PASSWORD) {
20
+ options.password = process.env.REDIS_PASSWORD;
21
+ }
22
+ const client = redis_1.default.createClient(options);
23
+ [
24
+ 'brpop',
25
+ 'del',
26
+ 'get',
27
+ 'hget',
28
+ 'rpop',
29
+ 'set',
30
+ 'zadd',
31
+ 'zrange',
32
+ 'zrangebyscore',
33
+ 'keys',
34
+ 'watch',
35
+ 'unwatch',
36
+ 'incr',
37
+ 'decr',
38
+ 'lpush'
39
+ ].forEach(k => {
40
+ client[`${k}Async`] = util_1.promisify(client[k]);
41
+ });
42
+ return client;
43
+ }
44
+ exports.createRedisClient = createRedisClient;
45
+ //# sourceMappingURL=RedisFactory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RedisFactory.js","sourceRoot":"","sources":["../../../src/orchestrator/RedisFactory.js"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAC1B,+BAAiC;AAEjC,SAAgB,iBAAiB,CAAC,GAAG;IACnC,eAAK,CAAC,KAAK,CAAC,SAAS,CAAC,SAAS,GAAG,SAAS,SAAS;QAClD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,CAC9D,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CACjC,CAAC,CAAC,CAAC;IACN,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG;QACd,GAAG;KACJ,CAAC;IAEF,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,MAAM,EAAE;QACpC,OAAO,CAAC,GAAG,GAAG,EAAE,CAAC;KAClB;IAED,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE;QAC9B,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;KAC/C;IAED,MAAM,MAAM,GAAG,eAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAE3C;QACE,OAAO;QACP,KAAK;QACL,KAAK;QACL,MAAM;QACN,MAAM;QACN,KAAK;QACL,MAAM;QACN,QAAQ;QACR,eAAe;QACf,MAAM;QACN,OAAO;QACP,SAAS;QACT,MAAM;QACN,MAAM;QACN,OAAO;KACR,CAAC,OAAO,CACP,CAAC,CAAC,EAAE;QACF,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,gBAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC,CACF,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC;AA5CD,8CA4CC"}
@@ -0,0 +1,10 @@
1
+ export class RedisPool {
2
+ constructor(options: any);
3
+ pool: genericPool.Pool<any>;
4
+ create: any;
5
+ getClient(): Promise<any>;
6
+ release(client: any): void;
7
+ cleanup(): Promise<void>;
8
+ }
9
+ import genericPool from "generic-pool";
10
+ //# sourceMappingURL=RedisPool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RedisPool.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/RedisPool.js"],"names":[],"mappings":"AAGA;IACE,0BAqBC;IALG,4BAA6D;IAG7D,YAAoB;IAIxB,0BAMC;IAED,2BAMC;IAED,yBAKC;CACF"}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.RedisPool = void 0;
7
+ const generic_pool_1 = __importDefault(require("generic-pool"));
8
+ const RedisFactory_1 = require("./RedisFactory");
9
+ class RedisPool {
10
+ constructor(options) {
11
+ options = options || {};
12
+ const defaultMin = process.env.CUBEJS_REDIS_POOL_MIN ? parseInt(process.env.CUBEJS_REDIS_POOL_MIN, 10) : 2;
13
+ const defaultMax = process.env.CUBEJS_REDIS_POOL_MAX ? parseInt(process.env.CUBEJS_REDIS_POOL_MAX, 10) : 1000;
14
+ const min = (typeof options.poolMin !== 'undefined') ? options.poolMin : defaultMin;
15
+ const max = (typeof options.poolMax !== 'undefined') ? options.poolMax : defaultMax;
16
+ const create = options.createClient || (() => RedisFactory_1.createRedisClient(process.env.REDIS_URL));
17
+ const destroy = options.destroyClient || (client => client.end(true));
18
+ const opts = {
19
+ min,
20
+ max,
21
+ acquireTimeoutMillis: 5000,
22
+ idleTimeoutMillis: 5000,
23
+ evictionRunIntervalMillis: 5000
24
+ };
25
+ if (max > 0) {
26
+ this.pool = generic_pool_1.default.createPool({ create, destroy }, opts);
27
+ }
28
+ else {
29
+ // fallback to un-pooled behavior if pool max is 0
30
+ this.create = create;
31
+ }
32
+ }
33
+ async getClient() {
34
+ if (this.pool) {
35
+ return this.pool.acquire();
36
+ }
37
+ else {
38
+ return this.create();
39
+ }
40
+ }
41
+ release(client) {
42
+ if (this.pool) {
43
+ this.pool.release(client);
44
+ }
45
+ else if (client) {
46
+ client.quit();
47
+ }
48
+ }
49
+ async cleanup() {
50
+ if (this.pool) {
51
+ await this.pool.drain();
52
+ this.pool.clear();
53
+ }
54
+ }
55
+ }
56
+ exports.RedisPool = RedisPool;
57
+ //# sourceMappingURL=RedisPool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RedisPool.js","sourceRoot":"","sources":["../../../src/orchestrator/RedisPool.js"],"names":[],"mappings":";;;;;;AAAA,gEAAuC;AACvC,iDAAmD;AAEnD,MAAa,SAAS;IACpB,YAAY,OAAO;QACjB,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC;QACxB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3G,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9G,MAAM,GAAG,GAAG,CAAC,OAAO,OAAO,CAAC,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC;QACpF,MAAM,GAAG,GAAG,CAAC,OAAO,OAAO,CAAC,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC;QACpF,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,IAAI,CAAC,GAAG,EAAE,CAAC,gCAAiB,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;QACxF,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QACtE,MAAM,IAAI,GAAG;YACX,GAAG;YACH,GAAG;YACH,oBAAoB,EAAE,IAAI;YAC1B,iBAAiB,EAAE,IAAI;YACvB,yBAAyB,EAAE,IAAI;SAChC,CAAC;QACF,IAAI,GAAG,GAAG,CAAC,EAAE;YACX,IAAI,CAAC,IAAI,GAAG,sBAAW,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;SAC/D;aAAM;YACL,kDAAkD;YAClD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;SACtB;IACH,CAAC;IAED,KAAK,CAAC,SAAS;QACb,IAAI,IAAI,CAAC,IAAI,EAAE;YACb,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;SAC5B;aAAM;YACL,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;SACtB;IACH,CAAC;IAED,OAAO,CAAC,MAAM;QACZ,IAAI,IAAI,CAAC,IAAI,EAAE;YACb,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;SAC3B;aAAM,IAAI,MAAM,EAAE;YACjB,MAAM,CAAC,IAAI,EAAE,CAAC;SACf;IACH,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,IAAI,EAAE;YACb,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;SACnB;IACH,CAAC;CACF;AA9CD,8BA8CC"}
@@ -0,0 +1,47 @@
1
+ export class RedisQueueDriverConnection {
2
+ constructor(driver: any, options: any);
3
+ driver: any;
4
+ redisClient: any;
5
+ redisQueuePrefix: any;
6
+ continueWaitTimeout: any;
7
+ orphanedTimeout: any;
8
+ heartBeatTimeout: any;
9
+ concurrency: any;
10
+ getResultBlocking(queryKey: any): Promise<any>;
11
+ getResult(queryKey: any): Promise<any>;
12
+ addToQueue(keyScore: any, queryKey: any, time: any, queryHandler: any, query: any, priority: any, options: any): any;
13
+ getToProcessQueries(): any;
14
+ getActiveQueries(): any;
15
+ getQueryAndRemove(queryKey: any): Promise<any[]>;
16
+ setResultAndRemoveQuery(queryKey: any, executionResult: any, processingId: any): Promise<any>;
17
+ getOrphanedQueries(): any;
18
+ getStalledQueries(): any;
19
+ getQueryStageState(onlyKeys: any): Promise<any[]>;
20
+ getQueryDef(queryKey: any): Promise<any>;
21
+ updateHeartBeat(queryKey: any): any;
22
+ getNextProcessingId(): Promise<any>;
23
+ retrieveForProcessing(queryKey: any, processingId: any): Promise<any>;
24
+ freeProcessingLock(queryKey: any, processingId: any, activated: any): Promise<any>;
25
+ optimisticQueryUpdate(queryKey: any, toUpdate: any, processingId: any): Promise<boolean>;
26
+ release(): any;
27
+ toProcessRedisKey(): string;
28
+ recentRedisKey(): string;
29
+ activeRedisKey(): string;
30
+ heartBeatRedisKey(): string;
31
+ queryRedisKey(queryKey: any, suffix: any): string;
32
+ queueRedisKey(suffix: any): string;
33
+ queriesDefKey(): string;
34
+ processingIdKey(): string;
35
+ resultListKey(queryKey: any): string;
36
+ queryProcessingLockKey(queryKey: any): string;
37
+ redisHash(queryKey: any): any;
38
+ }
39
+ export class RedisQueueDriver extends BaseQueueDriver {
40
+ constructor(options: any);
41
+ redisPool: any;
42
+ options: any;
43
+ createConnection(): Promise<RedisQueueDriverConnection>;
44
+ release(connection: any): void;
45
+ }
46
+ import { BaseQueueDriver } from "./BaseQueueDriver";
47
+ //# sourceMappingURL=RedisQueueDriver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RedisQueueDriver.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/RedisQueueDriver.js"],"names":[],"mappings":"AAGA;IACE,uCAQC;IAPC,YAAoB;IACpB,iBAAsC;IACtC,sBAAgD;IAChD,yBAAsD;IACtD,qBAA8C;IAC9C,sBAAgD;IAChD,iBAAsC;IAGxC,+CAWC;IAED,uCAIC;IAED,qHAmBC;IAED,2BAEC;IAED,wBAEC;IAED,iDAWC;IAED,8FAoBC;IAED,0BAIC;IAED,yBAIC;IAED,kDASC;IAED,yCAGC;IAED,oCAEC;IAED,oCAGC;IAED,sEA4BC;IAED,mFAoBC;IAED,yFA2BC;IAED,eAEC;IAED,4BAEC;IAED,yBAEC;IAED,yBAEC;IAED,4BAEC;IAED,kDAEC;IAED,mCAEC;IAED,wBAEC;IAED,0BAEC;IAED,qCAEC;IAED,8CAEC;IAED,8BAEC;CACF;AAED;IACE,0BAIC;IAFC,eAAkC;IAClC,aAAsB;IAGxB,wDAMC;IAED,+BAEC;CACF"}