qdone 2.0.47-alpha → 2.0.49-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/defaults.js +1 -1
- package/commonjs/src/enqueue.js +11 -2
- package/commonjs/src/idleQueues.js +98 -79
- package/npm-shrinkwrap.json +16000 -0
- package/package.json +1 -1
- package/src/defaults.js +1 -1
- package/src/enqueue.js +12 -1
- package/src/idleQueues.js +92 -78
package/package.json
CHANGED
package/src/defaults.js
CHANGED
|
@@ -133,7 +133,7 @@ export function getOptionsWithDefaults (options) {
|
|
|
133
133
|
// Idle Queues
|
|
134
134
|
idleFor: options.idleFor || options['idle-for'] || defaults.idleFor,
|
|
135
135
|
delete: options.delete || defaults.delete,
|
|
136
|
-
unpair: options.
|
|
136
|
+
unpair: options.unpair || defaults.unpair,
|
|
137
137
|
|
|
138
138
|
// Check
|
|
139
139
|
create: options.create || defaults.create,
|
package/src/enqueue.js
CHANGED
|
@@ -276,7 +276,18 @@ export async function sendMessageBatch (qrl, messages, opt) {
|
|
|
276
276
|
const promises = params.Entries.map(async m => ({ m, shouldEnqueue: await dedupShouldEnqueue(m, opt) }))
|
|
277
277
|
const results = await Promise.all(promises)
|
|
278
278
|
params.Entries = results.filter(({ shouldEnqueue }) => shouldEnqueue).map(({ m }) => m)
|
|
279
|
-
if (!params.Entries.length)
|
|
279
|
+
if (!params.Entries.length) {
|
|
280
|
+
const result = {
|
|
281
|
+
Failed: [],
|
|
282
|
+
Successful: results.map(
|
|
283
|
+
({ m: { Id: id, MessageAttributes: ma } }) => ({
|
|
284
|
+
Id: id,
|
|
285
|
+
MessageId: 'duplicate',
|
|
286
|
+
QdoneDeduplicationId: ma?.QdoneDeduplicationId?.StringValue
|
|
287
|
+
}))
|
|
288
|
+
}
|
|
289
|
+
return result
|
|
290
|
+
}
|
|
280
291
|
}
|
|
281
292
|
|
|
282
293
|
// Send them
|
package/src/idleQueues.js
CHANGED
|
@@ -7,7 +7,7 @@ import { getCloudWatchClient } from './cloudWatch.js'
|
|
|
7
7
|
import { getOptionsWithDefaults } from './defaults.js'
|
|
8
8
|
import { GetQueueAttributesCommand, DeleteQueueCommand, QueueDoesNotExist } from '@aws-sdk/client-sqs'
|
|
9
9
|
import { GetMetricStatisticsCommand } from '@aws-sdk/client-cloudwatch'
|
|
10
|
-
import { normalizeFailQueueName, getQnameUrlPairs, fifoSuffix } from './qrlCache.js'
|
|
10
|
+
import { normalizeFailQueueName, normalizeDLQName, getQnameUrlPairs, fifoSuffix } from './qrlCache.js'
|
|
11
11
|
import { getCache, setCache } from './cache.js'
|
|
12
12
|
// const AWS = require('aws-sdk')
|
|
13
13
|
|
|
@@ -37,6 +37,7 @@ const metricNames = [
|
|
|
37
37
|
* Actual SQS call, used in conjunction with cache.
|
|
38
38
|
*/
|
|
39
39
|
export async function _cheapIdleCheck (qname, qrl, opt) {
|
|
40
|
+
debug('_cheapIdleCheck', qname, qrl)
|
|
40
41
|
try {
|
|
41
42
|
const client = getSQSClient()
|
|
42
43
|
const cmd = new GetQueueAttributesCommand({ AttributeNames: attributeNames, QueueUrl: qrl })
|
|
@@ -46,11 +47,13 @@ export async function _cheapIdleCheck (qname, qrl, opt) {
|
|
|
46
47
|
result.queue = qname.slice(opt.prefix.length)
|
|
47
48
|
// We are idle if all the messages attributes are zero
|
|
48
49
|
result.idle = attributeNames.filter(k => result[k] === '0').length === attributeNames.length
|
|
50
|
+
result.exists = true
|
|
51
|
+
debug({ result, SQS: 1 })
|
|
49
52
|
return { result, SQS: 1 }
|
|
50
53
|
} catch (e) {
|
|
54
|
+
debug({ _cheapIdleCheck: e })
|
|
51
55
|
if (e instanceof QueueDoesNotExist) {
|
|
52
|
-
|
|
53
|
-
return { result: { idle: true }, SQS: 1 }
|
|
56
|
+
return { result: { idle: undefined, exists: false }, SQS: 1 }
|
|
54
57
|
} else {
|
|
55
58
|
throw e
|
|
56
59
|
}
|
|
@@ -62,6 +65,7 @@ export async function _cheapIdleCheck (qname, qrl, opt) {
|
|
|
62
65
|
* at this immediate moment.
|
|
63
66
|
*/
|
|
64
67
|
export async function cheapIdleCheck (qname, qrl, opt) {
|
|
68
|
+
debug('cheapIdleCheck', qname, qrl)
|
|
65
69
|
// Just call the API if we don't have a cache
|
|
66
70
|
if (!opt.cacheUri) return _cheapIdleCheck(qname, qrl, opt)
|
|
67
71
|
|
|
@@ -125,19 +129,20 @@ export async function checkIdle (qname, qrl, opt) {
|
|
|
125
129
|
const { result: cheapResult, SQS } = await cheapIdleCheck(qname, qrl, opt)
|
|
126
130
|
debug('cheapResult', cheapResult)
|
|
127
131
|
|
|
128
|
-
// Short circuit further calls if cheap result
|
|
129
|
-
if (cheapResult.idle === false) {
|
|
132
|
+
// Short circuit further calls if cheap result is conclusive
|
|
133
|
+
if (cheapResult.idle === false || cheapResult.exists === false) {
|
|
130
134
|
return {
|
|
131
135
|
queue: qname.slice(opt.prefix.length),
|
|
132
136
|
cheap: cheapResult,
|
|
133
|
-
idle:
|
|
137
|
+
idle: cheapResult.idle,
|
|
138
|
+
exists: cheapResult.exists,
|
|
134
139
|
apiCalls: { SQS, CloudWatch: 0 }
|
|
135
140
|
}
|
|
136
141
|
}
|
|
137
142
|
|
|
138
143
|
// If we get here, there's nothing in the queue at the moment,
|
|
139
144
|
// so we have to check metrics one at a time
|
|
140
|
-
const apiCalls = { SQS
|
|
145
|
+
const apiCalls = { SQS, CloudWatch: 0 }
|
|
141
146
|
const results = []
|
|
142
147
|
let idle = true
|
|
143
148
|
for (const metricName of metricNames) {
|
|
@@ -158,7 +163,8 @@ export async function checkIdle (qname, qrl, opt) {
|
|
|
158
163
|
queue: qname.slice(opt.prefix.length),
|
|
159
164
|
cheap: cheapResult,
|
|
160
165
|
apiCalls,
|
|
161
|
-
idle
|
|
166
|
+
idle,
|
|
167
|
+
exists: true
|
|
162
168
|
},
|
|
163
169
|
...results // merge in results from CloudWatch
|
|
164
170
|
)
|
|
@@ -210,92 +216,96 @@ export async function processQueue (qname, qrl, opt) {
|
|
|
210
216
|
}
|
|
211
217
|
|
|
212
218
|
/**
|
|
213
|
-
* Processes a queue and its fail queue, treating them as a unit.
|
|
219
|
+
* Processes a queue and its fail and delete queue, treating them as a unit.
|
|
214
220
|
*/
|
|
215
|
-
export async function
|
|
221
|
+
export async function processQueueSet (qname, qrl, opt) {
|
|
216
222
|
const isFifo = qname.endsWith('.fifo')
|
|
217
223
|
const normalizeOptions = Object.assign({}, opt, { fifo: isFifo })
|
|
224
|
+
|
|
225
|
+
// Generate DLQ name/url
|
|
226
|
+
const dqname = normalizeDLQName(qname, normalizeOptions)
|
|
227
|
+
const dqrl = normalizeDLQName(dqname, normalizeOptions)
|
|
228
|
+
|
|
218
229
|
// Generate fail queue name/url
|
|
219
230
|
const fqname = normalizeFailQueueName(qname, normalizeOptions)
|
|
220
231
|
const fqrl = normalizeFailQueueName(fqname, normalizeOptions)
|
|
221
232
|
|
|
222
|
-
|
|
223
|
-
const result = await checkIdle(qname, qrl, opt)
|
|
224
|
-
debug('result', result)
|
|
225
|
-
|
|
226
|
-
// Queue is active
|
|
227
|
-
const active = !result.idle
|
|
228
|
-
if (active) {
|
|
229
|
-
if (opt.verbose) console.error(chalk.blue('Queue ') + qname.slice(opt.prefix.length) + chalk.blue(' has been ') + 'active' + chalk.blue(' in the last ') + opt.idleFor + chalk.blue(' minutes.'))
|
|
230
|
-
return result
|
|
231
|
-
}
|
|
233
|
+
debug({ qname, qrl, dqname, dqrl, fqname, fqrl })
|
|
232
234
|
|
|
233
|
-
//
|
|
234
|
-
|
|
235
|
+
// Idle check
|
|
236
|
+
const qresult = await checkIdle(qname, qrl, opt)
|
|
237
|
+
const fqresult = await checkIdle(fqname, fqrl, opt)
|
|
238
|
+
const dqresult = await checkIdle(dqname, dqrl, opt)
|
|
239
|
+
debug({ qresult, fqresult, dqresult })
|
|
235
240
|
|
|
236
|
-
//
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
241
|
+
// Start building return value
|
|
242
|
+
const result = Object.assign(
|
|
243
|
+
{
|
|
244
|
+
queue: qname,
|
|
245
|
+
idle: (
|
|
246
|
+
qresult.idle &&
|
|
247
|
+
(!fqresult.exists || fqresult.idle) &&
|
|
248
|
+
(!fqresult.exists || dqresult.idle)
|
|
249
|
+
),
|
|
250
|
+
apiCalls: {
|
|
251
|
+
SQS: qresult.apiCalls.SQS + fqresult.apiCalls.SQS + dqresult.apiCalls.SQS,
|
|
252
|
+
CloudWatch: qresult.apiCalls.CloudWatch + fqresult.apiCalls.CloudWatch + dqresult.apiCalls.CloudWatch
|
|
248
253
|
}
|
|
249
|
-
)
|
|
250
|
-
|
|
251
|
-
// Queue is active
|
|
252
|
-
const factive = !fresult.idle
|
|
253
|
-
if (factive) {
|
|
254
|
-
if (opt.verbose) console.error(chalk.blue('Queue ') + fqname.slice(opt.prefix.length) + chalk.blue(' has been ') + 'active' + chalk.blue(' in the last ') + opt.idleFor + chalk.blue(' minutes.'))
|
|
255
|
-
return idleCheckResult
|
|
256
254
|
}
|
|
255
|
+
)
|
|
257
256
|
|
|
258
|
-
|
|
259
|
-
|
|
257
|
+
// Queue is idle
|
|
258
|
+
if (qresult.idle && opt.verbose) console.error(chalk.blue('Queue ') + qname.slice(opt.prefix.length) + chalk.blue(' has been ') + 'idle' + chalk.blue(' for the last ') + opt.idleFor + chalk.blue(' minutes.'))
|
|
259
|
+
if (fqresult.idle && opt.verbose) console.error(chalk.blue('Queue ') + fqname.slice(opt.prefix.length) + chalk.blue(' has been ') + 'idle' + chalk.blue(' for the last ') + opt.idleFor + chalk.blue(' minutes.'))
|
|
260
|
+
if (dqresult.idle && opt.verbose) console.error(chalk.blue('Queue ') + dqname.slice(opt.prefix.length) + chalk.blue(' has been ') + 'idle' + chalk.blue(' for the last ') + opt.idleFor + chalk.blue(' minutes.'))
|
|
260
261
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
262
|
+
// Delete if all are idle
|
|
263
|
+
const canDelete = (
|
|
264
|
+
(qresult.idle || qresult.exists === false) &&
|
|
265
|
+
(fqresult.idle || fqresult.exists === false) &&
|
|
266
|
+
(dqresult.idle || dqresult.exists === false)
|
|
267
|
+
)
|
|
268
|
+
debug({ canDelete })
|
|
269
|
+
|
|
270
|
+
if (opt.delete && canDelete) {
|
|
271
|
+
// Normal
|
|
272
|
+
const qdresult = await (async () => {
|
|
273
|
+
debug({ qresult })
|
|
274
|
+
try {
|
|
275
|
+
if (qresult.idle) return deleteQueue(qname, qrl, opt)
|
|
276
|
+
} catch (e) {
|
|
277
|
+
if (!(e instanceof QueueDoesNotExist)) throw e
|
|
277
278
|
}
|
|
278
|
-
})
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
// created for some reason
|
|
282
|
-
if (!(e instanceof QueueDoesNotExist)) throw e
|
|
279
|
+
})()
|
|
280
|
+
if (qdresult) { result.apiCalls.SQS += qdresult.apiCalls.SQS }
|
|
281
|
+
debug({ qdresult })
|
|
283
282
|
|
|
284
|
-
// Fail
|
|
285
|
-
|
|
283
|
+
// Fail
|
|
284
|
+
const fqdresult = await (async () => {
|
|
285
|
+
debug({ fqresult })
|
|
286
|
+
try {
|
|
287
|
+
if (fqresult.idle) return deleteQueue(fqname, fqrl, opt)
|
|
288
|
+
} catch (e) {
|
|
289
|
+
if (!(e instanceof QueueDoesNotExist)) throw e
|
|
290
|
+
}
|
|
291
|
+
})()
|
|
292
|
+
if (fqdresult) { result.apiCalls.SQS += fqdresult.apiCalls.SQS }
|
|
293
|
+
debug({ fqdresult })
|
|
286
294
|
|
|
287
|
-
//
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
CloudWatch: result.apiCalls.CloudWatch + deleteResult.apiCalls.CloudWatch
|
|
295
|
+
// Dead
|
|
296
|
+
const dqdresult = await (async () => {
|
|
297
|
+
debug({ dqresult })
|
|
298
|
+
try {
|
|
299
|
+
if (dqresult.idle) return deleteQueue(dqname, dqrl, opt)
|
|
300
|
+
} catch (e) {
|
|
301
|
+
if (!(e instanceof QueueDoesNotExist)) throw e
|
|
295
302
|
}
|
|
296
|
-
})
|
|
297
|
-
|
|
303
|
+
})()
|
|
304
|
+
if (dqdresult) { result.apiCalls.SQS += dqdresult.apiCalls.SQS }
|
|
305
|
+
debug({ dqdresult })
|
|
298
306
|
}
|
|
307
|
+
|
|
308
|
+
return result
|
|
299
309
|
}
|
|
300
310
|
|
|
301
311
|
//
|
|
@@ -318,7 +328,11 @@ export async function idleQueues (queues, options) {
|
|
|
318
328
|
const sufFifo = opt.failSuffix + fifoSuffix
|
|
319
329
|
const isFail = entry.qname.endsWith(suf)
|
|
320
330
|
const isFifoFail = entry.qname.endsWith(sufFifo)
|
|
321
|
-
|
|
331
|
+
const sufDead = opt.dlqSuffix
|
|
332
|
+
const sufFifoDead = opt.dlqSuffix + fifoSuffix
|
|
333
|
+
const isDead = entry.qname.endsWith(sufDead)
|
|
334
|
+
const isFifoDead = entry.qname.endsWith(sufFifoDead)
|
|
335
|
+
return opt.includeFailed ? true : (!isFail && !isFifoFail && !isDead && !isFifoDead)
|
|
322
336
|
})
|
|
323
337
|
|
|
324
338
|
// But only if we have queues to remove
|
|
@@ -332,7 +346,7 @@ export async function idleQueues (queues, options) {
|
|
|
332
346
|
}
|
|
333
347
|
// Check each queue in parallel
|
|
334
348
|
if (opt.unpair) return Promise.all(filteredEntries.map(e => processQueue(e.qname, e.qrl, opt)))
|
|
335
|
-
return Promise.all(filteredEntries.map(e =>
|
|
349
|
+
return Promise.all(filteredEntries.map(e => processQueueSet(e.qname, e.qrl, opt)))
|
|
336
350
|
}
|
|
337
351
|
|
|
338
352
|
// Otherwise, let caller know
|