qdone 2.0.28-alpha → 2.0.30-alpha
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/commonjs/src/cache.js +22 -93
- package/commonjs/src/cloudWatch.js +65 -111
- package/commonjs/src/consumer.js +135 -237
- package/commonjs/src/defaults.js +11 -11
- package/commonjs/src/enqueue.js +311 -503
- package/commonjs/src/exponentialBackoff.js +39 -110
- package/commonjs/src/idleQueues.js +255 -396
- package/commonjs/src/monitor.js +42 -115
- package/commonjs/src/qrlCache.js +80 -162
- package/commonjs/src/scheduler/jobExecutor.js +305 -363
- package/commonjs/src/scheduler/queueManager.js +116 -190
- package/commonjs/src/scheduler/systemMonitor.js +24 -28
- package/commonjs/src/sqs.js +58 -141
- package/package.json +2 -2
- package/src/consumer.js +3 -5
- package/src/defaults.js +3 -3
- package/src/enqueue.js +1 -1
- package/src/scheduler/jobExecutor.js +77 -33
- package/src/scheduler/queueManager.js +13 -4
- package/npm-shrinkwrap.json +0 -15999
|
@@ -2,55 +2,18 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Component to manange what queues are being listened to and in what order.
|
|
4
4
|
*/
|
|
5
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
6
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
7
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
8
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
9
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
10
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
11
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
12
|
-
});
|
|
13
|
-
};
|
|
14
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
15
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
16
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
17
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
18
|
-
function step(op) {
|
|
19
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
20
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
21
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
22
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
23
|
-
switch (op[0]) {
|
|
24
|
-
case 0: case 1: t = op; break;
|
|
25
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
26
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
27
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
28
|
-
default:
|
|
29
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
30
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
31
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
32
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
33
|
-
if (t[2]) _.ops.pop();
|
|
34
|
-
_.trys.pop(); continue;
|
|
35
|
-
}
|
|
36
|
-
op = body.call(thisArg, _);
|
|
37
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
38
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
5
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
42
6
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
43
7
|
};
|
|
44
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
9
|
exports.QueueManager = void 0;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (resolveSeconds === void 0) { resolveSeconds = 10; }
|
|
10
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
11
|
+
const debug_1 = __importDefault(require("debug"));
|
|
12
|
+
const qrlCache_js_1 = require("../qrlCache.js");
|
|
13
|
+
const idleQueues_js_1 = require("../idleQueues.js");
|
|
14
|
+
const debug = (0, debug_1.default)('qdone:queueManager');
|
|
15
|
+
class QueueManager {
|
|
16
|
+
constructor(opt, queues, resolveSeconds = 10) {
|
|
54
17
|
this.opt = opt;
|
|
55
18
|
this.queues = queues;
|
|
56
19
|
this.resolveSeconds = resolveSeconds;
|
|
@@ -62,173 +25,136 @@ var QueueManager = /** @class */ (function () {
|
|
|
62
25
|
}
|
|
63
26
|
// Sends a queue to the icehouse, where it waits for a while before being
|
|
64
27
|
// checked again
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
28
|
+
updateIcehouse(qrl, emptyReceive) {
|
|
29
|
+
const foundEntry = !!this.icehouse[qrl];
|
|
30
|
+
const { lastCheck, secondsToWait, numEmptyReceives } = this.icehouse[qrl] || {
|
|
68
31
|
lastCheck: new Date(),
|
|
69
32
|
secondsToWait: Math.round(20 + 10 * Math.random()),
|
|
70
33
|
numEmptyReceives: 0 + emptyReceive
|
|
71
|
-
}
|
|
34
|
+
};
|
|
72
35
|
if (emptyReceive) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
36
|
+
const now = new Date();
|
|
37
|
+
const secondsElapsed = lastCheck - now;
|
|
38
|
+
const minWait = 10;
|
|
39
|
+
const maxWait = 120;
|
|
40
|
+
const baseSeconds = numEmptyReceives ** 2 * 20;
|
|
41
|
+
const jitterSeconds = Math.round((Math.random() - 0.5) * baseSeconds);
|
|
42
|
+
const newSecondsToWait = Math.max(minWait, Math.min(maxWait, baseSeconds + jitterSeconds));
|
|
43
|
+
const newEntry = { lastCheck: now, secondsToWait: newSecondsToWait, numEmptyReceives: numEmptyReceives + 1 };
|
|
81
44
|
this.icehouse[qrl] = newEntry;
|
|
82
45
|
if (this.opt.verbose) {
|
|
83
46
|
console.error(chalk_1.default.blue('Sending queue to icehouse'), qrl, chalk_1.default.blue('for'), newSecondsToWait, chalk_1.default.blue('seconds'));
|
|
84
47
|
}
|
|
85
|
-
debug({ foundEntry
|
|
48
|
+
debug({ foundEntry, newEntry, lastCheck, secondsToWait, now, secondsElapsed, maxWait, minWait, baseSeconds, jitterSeconds });
|
|
86
49
|
}
|
|
87
50
|
else {
|
|
88
51
|
delete this.icehouse[qrl];
|
|
89
52
|
}
|
|
90
|
-
}
|
|
53
|
+
}
|
|
91
54
|
// Returns true if the queue should be kept in the icehouse
|
|
92
|
-
|
|
55
|
+
keepInIcehouse(qrl, now) {
|
|
93
56
|
if (this.icehouse[qrl]) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
debug({ icehouseCheck: { qrl
|
|
97
|
-
|
|
98
|
-
if (letOut
|
|
99
|
-
|
|
57
|
+
const { lastCheck, secondsToWait } = this.icehouse[qrl];
|
|
58
|
+
const secondsElapsed = Math.round((now - lastCheck) / 1000);
|
|
59
|
+
debug({ icehouseCheck: { qrl, lastCheck, secondsToWait, secondsElapsed } });
|
|
60
|
+
const letOut = secondsElapsed > secondsToWait;
|
|
61
|
+
if (letOut) {
|
|
62
|
+
delete this.icehouse[qrl];
|
|
63
|
+
if (this.opt.verbose) {
|
|
64
|
+
console.error(chalk_1.default.blue('Coming out of icehouse:'), qrl);
|
|
65
|
+
}
|
|
100
66
|
}
|
|
101
67
|
return !letOut;
|
|
102
68
|
}
|
|
103
69
|
else {
|
|
104
70
|
return false;
|
|
105
71
|
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
_a.label = 3;
|
|
176
|
-
case 3:
|
|
177
|
-
if (this.shutdownRequested)
|
|
178
|
-
return [2 /*return*/];
|
|
179
|
-
// Figure out which queues we want to listen on, choosing between active and
|
|
180
|
-
// all, filtering out failed queues if the user wants that
|
|
181
|
-
this.selectedPairs = (this.opt.activeOnly ? activePairs : filteredPairs);
|
|
182
|
-
// Randomize order
|
|
183
|
-
this.selectedPairs.sort(function () { return 0.5 - Math.random(); });
|
|
184
|
-
if (this.opt.verbose)
|
|
185
|
-
console.error(chalk_1.default.blue(' selected:\n ') + this.selectedPairs.map(function (_a) {
|
|
186
|
-
var qname = _a.qname;
|
|
187
|
-
return qname;
|
|
188
|
-
}).join('\n '));
|
|
189
|
-
debug('selectedPairs', this.selectedPairs);
|
|
190
|
-
// Finished resolving
|
|
191
|
-
if (this.opt.verbose) {
|
|
192
|
-
console.error(chalk_1.default.blue('Done resolving'));
|
|
193
|
-
console.error();
|
|
194
|
-
}
|
|
195
|
-
return [2 /*return*/];
|
|
196
|
-
}
|
|
197
|
-
});
|
|
198
|
-
});
|
|
199
|
-
};
|
|
72
|
+
}
|
|
73
|
+
async resolveQueues() {
|
|
74
|
+
clearTimeout(this.resolveTimeout);
|
|
75
|
+
if (this.shutdownRequested)
|
|
76
|
+
return;
|
|
77
|
+
this.resolveTimeout = setTimeout(() => {
|
|
78
|
+
this.resolvePromise = this.resolveQueues();
|
|
79
|
+
}, this.resolveSeconds * 1000);
|
|
80
|
+
if (this.opt.verbose) {
|
|
81
|
+
console.error(chalk_1.default.blue('Will resolve queues again in ' + this.resolveSeconds + ' seconds'));
|
|
82
|
+
}
|
|
83
|
+
// Start processing
|
|
84
|
+
const qnames = this.queues.map(queue => (0, qrlCache_js_1.normalizeQueueName)(queue, this.opt));
|
|
85
|
+
const pairs = await (0, qrlCache_js_1.getQnameUrlPairs)(qnames, this.opt);
|
|
86
|
+
if (this.opt.verbose)
|
|
87
|
+
console.error(chalk_1.default.blue('Resolving queues:'), pairs.map(({ qname }) => qname));
|
|
88
|
+
if (this.shutdownRequested)
|
|
89
|
+
return;
|
|
90
|
+
// Filter out queues
|
|
91
|
+
const now = new Date();
|
|
92
|
+
const filteredPairs = pairs
|
|
93
|
+
// first failed
|
|
94
|
+
.filter(({ qname, qrl }) => {
|
|
95
|
+
const suf = this.opt.failSuffix + (this.opt.fifo ? '.fifo' : '');
|
|
96
|
+
const isFailQueue = qname.slice(-suf.length) === suf;
|
|
97
|
+
return this.opt.includeFailed ? true : !isFailQueue;
|
|
98
|
+
})
|
|
99
|
+
// next fifo
|
|
100
|
+
.filter(({ qname, qrl }) => {
|
|
101
|
+
const isFifo = qname.endsWith('.fifo');
|
|
102
|
+
return this.opt.fifo ? isFifo : true;
|
|
103
|
+
})
|
|
104
|
+
// next dead
|
|
105
|
+
.filter(({ qname, qrl }) => {
|
|
106
|
+
const isFifo = qname.endsWith('.fifo');
|
|
107
|
+
const isDead = isFifo ? qname.endsWith('_dead.fifo') : qname.endsWith('_dead');
|
|
108
|
+
return !isDead;
|
|
109
|
+
})
|
|
110
|
+
// then icehouse
|
|
111
|
+
.filter(({ qname, qrl }) => !this.keepInIcehouse(qrl, now));
|
|
112
|
+
// Figure out which pairs are active
|
|
113
|
+
const activePairs = [];
|
|
114
|
+
if (this.opt.activeOnly) {
|
|
115
|
+
if (this.opt.verbose) {
|
|
116
|
+
console.error(chalk_1.default.blue(' checking active only'));
|
|
117
|
+
}
|
|
118
|
+
await Promise.all(filteredPairs.map(async ({ qname, qrl }) => {
|
|
119
|
+
const { result: { idle } } = await (0, idleQueues_js_1.cheapIdleCheck)(qname, qrl, this.opt);
|
|
120
|
+
debug({ idle, qname });
|
|
121
|
+
if (!idle)
|
|
122
|
+
activePairs.push({ qname, qrl });
|
|
123
|
+
}));
|
|
124
|
+
}
|
|
125
|
+
if (this.shutdownRequested)
|
|
126
|
+
return;
|
|
127
|
+
// Figure out which queues we want to listen on, choosing between active and
|
|
128
|
+
// all, filtering out failed queues if the user wants that
|
|
129
|
+
this.selectedPairs = (this.opt.activeOnly ? activePairs : filteredPairs);
|
|
130
|
+
// Randomize order
|
|
131
|
+
this.selectedPairs.sort(() => 0.5 - Math.random());
|
|
132
|
+
if (this.opt.verbose)
|
|
133
|
+
console.error(chalk_1.default.blue(' selected:\n ') + this.selectedPairs.map(({ qname }) => qname).join('\n '));
|
|
134
|
+
debug('selectedPairs', this.selectedPairs);
|
|
135
|
+
// Finished resolving
|
|
136
|
+
if (this.opt.verbose) {
|
|
137
|
+
console.error(chalk_1.default.blue('Done resolving'));
|
|
138
|
+
console.error();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
200
141
|
// Return the next queue in the lineup
|
|
201
|
-
|
|
202
|
-
|
|
142
|
+
nextPair() {
|
|
143
|
+
const pair = this.selectedPairs.shift();
|
|
203
144
|
this.selectedPairs.push(pair);
|
|
204
145
|
return pair;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
this.shutdownRequested = true;
|
|
220
|
-
clearTimeout(this.resolveTimeout);
|
|
221
|
-
if (this.opt.verbose) {
|
|
222
|
-
console.error(chalk_1.default.blue('Waiting for queues to resolve'));
|
|
223
|
-
}
|
|
224
|
-
return [4 /*yield*/, this.resolvePromise];
|
|
225
|
-
case 1:
|
|
226
|
-
_a.sent();
|
|
227
|
-
return [2 /*return*/];
|
|
228
|
-
}
|
|
229
|
-
});
|
|
230
|
-
});
|
|
231
|
-
};
|
|
232
|
-
return QueueManager;
|
|
233
|
-
}());
|
|
146
|
+
}
|
|
147
|
+
getPairs() {
|
|
148
|
+
const now = new Date();
|
|
149
|
+
return this.selectedPairs.filter(({ qname, qrl }) => !this.keepInIcehouse(qrl, now));
|
|
150
|
+
}
|
|
151
|
+
async shutdown() {
|
|
152
|
+
this.shutdownRequested = true;
|
|
153
|
+
clearTimeout(this.resolveTimeout);
|
|
154
|
+
if (this.opt.verbose) {
|
|
155
|
+
console.error(chalk_1.default.blue('Waiting for queues to resolve'));
|
|
156
|
+
}
|
|
157
|
+
await this.resolvePromise;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
234
160
|
exports.QueueManager = QueueManager;
|
|
@@ -5,45 +5,41 @@
|
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.SystemMonitor = void 0;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (reportSeconds === void 0) { reportSeconds = 1; }
|
|
8
|
+
class SystemMonitor {
|
|
9
|
+
constructor(reportCallback, reportSeconds = 1) {
|
|
11
10
|
this.reportCallback = reportCallback || console.log;
|
|
12
11
|
this.reportSeconds = reportSeconds;
|
|
13
12
|
this.measurements = [];
|
|
14
13
|
this.measure();
|
|
15
14
|
this.reportLatency();
|
|
16
15
|
}
|
|
17
|
-
|
|
18
|
-
var _this = this;
|
|
16
|
+
measure() {
|
|
19
17
|
clearTimeout(this.measureTimeout);
|
|
20
|
-
|
|
21
|
-
this.measureTimeout = setTimeout(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
const start = new Date();
|
|
19
|
+
this.measureTimeout = setTimeout(() => {
|
|
20
|
+
const latency = new Date() - start;
|
|
21
|
+
this.measurements.push(latency);
|
|
22
|
+
if (this.measurements.length > 1000)
|
|
23
|
+
this.measurements.shift();
|
|
24
|
+
this.measure();
|
|
27
25
|
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return this.measurements.length ? this.measurements.reduce(
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
var _this = this;
|
|
26
|
+
}
|
|
27
|
+
getLatency() {
|
|
28
|
+
return this.measurements.length ? this.measurements.reduce((a, b) => a + b, 0) / this.measurements.length : 0;
|
|
29
|
+
}
|
|
30
|
+
reportLatency() {
|
|
34
31
|
clearTimeout(this.reportTimeout);
|
|
35
|
-
this.reportTimeout = setTimeout(
|
|
36
|
-
|
|
32
|
+
this.reportTimeout = setTimeout(() => {
|
|
33
|
+
const latency = this.getLatency();
|
|
37
34
|
// console.log({ latency })
|
|
38
|
-
if (
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
if (this.reportCallback)
|
|
36
|
+
this.reportCallback(latency);
|
|
37
|
+
this.reportLatency();
|
|
41
38
|
}, this.reportSeconds * 1000);
|
|
42
|
-
}
|
|
43
|
-
|
|
39
|
+
}
|
|
40
|
+
shutdown() {
|
|
44
41
|
clearTimeout(this.measureTimeout);
|
|
45
42
|
clearTimeout(this.reportTimeout);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
}());
|
|
43
|
+
}
|
|
44
|
+
}
|
|
49
45
|
exports.SystemMonitor = SystemMonitor;
|