sqs-consumer 6.2.1 → 7.0.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/.github/workflows/coverage.yml +1 -1
- package/.github/workflows/issues-to-projects.yml +17 -0
- package/.github/workflows/test.yml +1 -1
- package/README.md +13 -2
- package/dist/consumer.d.ts +6 -2
- package/dist/consumer.js +18 -6
- package/dist/controllers.d.ts +1 -0
- package/dist/controllers.js +4 -0
- package/dist/types.d.ts +12 -0
- package/package.json +4 -1
- package/src/consumer.ts +36 -7
- package/src/controllers.ts +1 -0
- package/src/types.ts +13 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: Add bugs to bugs project
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
issues:
|
|
5
|
+
types:
|
|
6
|
+
- opened
|
|
7
|
+
- labeled
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
add-to-project:
|
|
11
|
+
name: Add issue to project
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/add-to-project@v0.4.0
|
|
15
|
+
with:
|
|
16
|
+
project-url: https://github.com/orgs/bbc/projects/170
|
|
17
|
+
github-token: ${{ secrets.ADD_TO_PROJECT_PAT }}
|
package/README.md
CHANGED
|
@@ -22,6 +22,12 @@ npm install --save-dev sqs-consumer
|
|
|
22
22
|
> npm install sqs-consumer@5.8.0 --save-dev
|
|
23
23
|
> ```
|
|
24
24
|
|
|
25
|
+
### Node version
|
|
26
|
+
|
|
27
|
+
From v7 and above, this library will only support Node v16 or above. If you are still using Node 14, please use a previous version of the library.
|
|
28
|
+
|
|
29
|
+
This decision was made due to the removal of security support from the Node.JS team from April 30th, 2023.
|
|
30
|
+
|
|
25
31
|
## Usage
|
|
26
32
|
|
|
27
33
|
```js
|
|
@@ -49,6 +55,7 @@ app.start();
|
|
|
49
55
|
- Messages are deleted from the queue once the handler function has completed successfully.
|
|
50
56
|
- Throwing an error (or returning a rejected promise) from the handler function will cause the message to be left on the queue. An [SQS redrive policy](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/SQSDeadLetterQueue.html) can be used to move messages that cannot be processed to a dead letter queue.
|
|
51
57
|
- By default messages are processed one at a time – a new message won't be received until the first one has been processed. To process messages in parallel, use the `batchSize` option [detailed below](#options).
|
|
58
|
+
- By default, messages that are sent to the `handleMessage` and `handleMessageBatch` functions will be considered as processed if they return without an error. To acknowledge individual messages, please return the message that you want to acknowledge if you are using `handleMessage` or the messages for `handleMessageBatch`. It's also important to await any processing that you are doing to ensure that messages are processed one at a time.
|
|
52
59
|
|
|
53
60
|
### Credentials
|
|
54
61
|
|
|
@@ -108,9 +115,13 @@ Creates a new SQS consumer using the [defined options](https://bbc.github.io/sqs
|
|
|
108
115
|
|
|
109
116
|
Start polling the queue for messages.
|
|
110
117
|
|
|
111
|
-
### `consumer.stop()`
|
|
118
|
+
### `consumer.stop(options)`
|
|
119
|
+
|
|
120
|
+
Stop polling the queue for messages. [You can find the options definition here](https://bbc.github.io/sqs-consumer/interfaces/StopOptions.html).
|
|
121
|
+
|
|
122
|
+
By default, the value of `abort` is set to `false` which means pre existing requests to AWS SQS will still be made until they have concluded. If you would like to abort these requests instead, pass the abort value as `true`, like so:
|
|
112
123
|
|
|
113
|
-
|
|
124
|
+
`consumer.stop({ abort: true })`
|
|
114
125
|
|
|
115
126
|
### `consumer.isRunning`
|
|
116
127
|
|
package/dist/consumer.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ConsumerOptions, TypedEventEmitter } from './types';
|
|
1
|
+
import { ConsumerOptions, TypedEventEmitter, StopOptions } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* [Usage](https://bbc.github.io/sqs-consumer/index.html#usage)
|
|
4
4
|
*/
|
|
@@ -34,7 +34,7 @@ export declare class Consumer extends TypedEventEmitter {
|
|
|
34
34
|
/**
|
|
35
35
|
* Stop polling the queue for messages (pre existing requests will still be made until concluded).
|
|
36
36
|
*/
|
|
37
|
-
stop(): void;
|
|
37
|
+
stop(options: StopOptions): void;
|
|
38
38
|
/**
|
|
39
39
|
* Returns the current polling state of the consumer: `true` if it is actively polling, `false` if it is not.
|
|
40
40
|
*/
|
|
@@ -45,6 +45,10 @@ export declare class Consumer extends TypedEventEmitter {
|
|
|
45
45
|
* @param message The message that the error occurred on
|
|
46
46
|
*/
|
|
47
47
|
private emitError;
|
|
48
|
+
/**
|
|
49
|
+
* A reusable options object for sqs.send that's used to avoid duplication.
|
|
50
|
+
*/
|
|
51
|
+
private sqsSendOptions;
|
|
48
52
|
/**
|
|
49
53
|
* Poll for new messages from SQS
|
|
50
54
|
*/
|
package/dist/consumer.js
CHANGED
|
@@ -7,6 +7,7 @@ const types_1 = require("./types");
|
|
|
7
7
|
const bind_1 = require("./bind");
|
|
8
8
|
const errors_1 = require("./errors");
|
|
9
9
|
const validation_1 = require("./validation");
|
|
10
|
+
const controllers_1 = require("./controllers");
|
|
10
11
|
const debug = (0, debug_1.default)('sqs-consumer');
|
|
11
12
|
/**
|
|
12
13
|
* [Usage](https://bbc.github.io/sqs-consumer/index.html#usage)
|
|
@@ -19,6 +20,12 @@ class Consumer extends types_1.TypedEventEmitter {
|
|
|
19
20
|
this.heartbeatTimeoutId = undefined;
|
|
20
21
|
this.handleMessageTimeoutId = undefined;
|
|
21
22
|
this.stopped = true;
|
|
23
|
+
/**
|
|
24
|
+
* A reusable options object for sqs.send that's used to avoid duplication.
|
|
25
|
+
*/
|
|
26
|
+
this.sqsSendOptions = {
|
|
27
|
+
abortSignal: controllers_1.abortController.signal
|
|
28
|
+
};
|
|
22
29
|
(0, validation_1.assertOptions)(options);
|
|
23
30
|
this.queueUrl = options.queueUrl;
|
|
24
31
|
this.handleMessage = options.handleMessage;
|
|
@@ -62,7 +69,7 @@ class Consumer extends types_1.TypedEventEmitter {
|
|
|
62
69
|
/**
|
|
63
70
|
* Stop polling the queue for messages (pre existing requests will still be made until concluded).
|
|
64
71
|
*/
|
|
65
|
-
stop() {
|
|
72
|
+
stop(options) {
|
|
66
73
|
if (this.stopped) {
|
|
67
74
|
debug('Consumer was already stopped');
|
|
68
75
|
return;
|
|
@@ -73,6 +80,11 @@ class Consumer extends types_1.TypedEventEmitter {
|
|
|
73
80
|
clearTimeout(this.pollingTimeoutId);
|
|
74
81
|
this.pollingTimeoutId = undefined;
|
|
75
82
|
}
|
|
83
|
+
if (options === null || options === void 0 ? void 0 : options.abort) {
|
|
84
|
+
debug('Aborting SQS requests');
|
|
85
|
+
controllers_1.abortController.abort();
|
|
86
|
+
this.emit('aborted');
|
|
87
|
+
}
|
|
76
88
|
this.emit('stopped');
|
|
77
89
|
}
|
|
78
90
|
/**
|
|
@@ -143,7 +155,7 @@ class Consumer extends types_1.TypedEventEmitter {
|
|
|
143
155
|
*/
|
|
144
156
|
async receiveMessage(params) {
|
|
145
157
|
try {
|
|
146
|
-
return await this.sqs.send(new client_sqs_1.ReceiveMessageCommand(params));
|
|
158
|
+
return await this.sqs.send(new client_sqs_1.ReceiveMessageCommand(params), this.sqsSendOptions);
|
|
147
159
|
}
|
|
148
160
|
catch (err) {
|
|
149
161
|
throw (0, errors_1.toSQSError)(err, `SQS receive message failed: ${err.message}`);
|
|
@@ -253,7 +265,7 @@ class Consumer extends types_1.TypedEventEmitter {
|
|
|
253
265
|
ReceiptHandle: message.ReceiptHandle,
|
|
254
266
|
VisibilityTimeout: timeout
|
|
255
267
|
};
|
|
256
|
-
return await this.sqs.send(new client_sqs_1.ChangeMessageVisibilityCommand(input));
|
|
268
|
+
return await this.sqs.send(new client_sqs_1.ChangeMessageVisibilityCommand(input), this.sqsSendOptions);
|
|
257
269
|
}
|
|
258
270
|
catch (err) {
|
|
259
271
|
this.emit('error', (0, errors_1.toSQSError)(err, `Error changing visibility timeout: ${err.message}`), message);
|
|
@@ -274,7 +286,7 @@ class Consumer extends types_1.TypedEventEmitter {
|
|
|
274
286
|
}))
|
|
275
287
|
};
|
|
276
288
|
try {
|
|
277
|
-
return await this.sqs.send(new client_sqs_1.ChangeMessageVisibilityBatchCommand(params));
|
|
289
|
+
return await this.sqs.send(new client_sqs_1.ChangeMessageVisibilityBatchCommand(params), this.sqsSendOptions);
|
|
278
290
|
}
|
|
279
291
|
catch (err) {
|
|
280
292
|
this.emit('error', (0, errors_1.toSQSError)(err, `Error changing visibility timeout: ${err.message}`), messages);
|
|
@@ -342,7 +354,7 @@ class Consumer extends types_1.TypedEventEmitter {
|
|
|
342
354
|
ReceiptHandle: message.ReceiptHandle
|
|
343
355
|
};
|
|
344
356
|
try {
|
|
345
|
-
await this.sqs.send(new client_sqs_1.DeleteMessageCommand(deleteParams));
|
|
357
|
+
await this.sqs.send(new client_sqs_1.DeleteMessageCommand(deleteParams), this.sqsSendOptions);
|
|
346
358
|
}
|
|
347
359
|
catch (err) {
|
|
348
360
|
throw (0, errors_1.toSQSError)(err, `SQS delete message failed: ${err.message}`);
|
|
@@ -366,7 +378,7 @@ class Consumer extends types_1.TypedEventEmitter {
|
|
|
366
378
|
}))
|
|
367
379
|
};
|
|
368
380
|
try {
|
|
369
|
-
await this.sqs.send(new client_sqs_1.DeleteMessageBatchCommand(deleteParams));
|
|
381
|
+
await this.sqs.send(new client_sqs_1.DeleteMessageBatchCommand(deleteParams), this.sqsSendOptions);
|
|
370
382
|
}
|
|
371
383
|
catch (err) {
|
|
372
384
|
throw (0, errors_1.toSQSError)(err, `SQS delete message failed: ${err.message}`);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const abortController: AbortController;
|
package/dist/types.d.ts
CHANGED
|
@@ -105,6 +105,14 @@ export interface ConsumerOptions {
|
|
|
105
105
|
*/
|
|
106
106
|
handleMessageBatch?(messages: Message[]): Promise<Message[] | void>;
|
|
107
107
|
}
|
|
108
|
+
export interface StopOptions {
|
|
109
|
+
/**
|
|
110
|
+
* Default to `false`, if you want the stop action to also abort requests to SQS
|
|
111
|
+
* set this to `true`.
|
|
112
|
+
* @defaultvalue `false`
|
|
113
|
+
*/
|
|
114
|
+
abort?: boolean;
|
|
115
|
+
}
|
|
108
116
|
export interface Events {
|
|
109
117
|
/**
|
|
110
118
|
* Fired after one batch of items (up to `batchSize`) has been successfully processed.
|
|
@@ -137,6 +145,10 @@ export interface Events {
|
|
|
137
145
|
* Fired when an error occurs processing the message.
|
|
138
146
|
*/
|
|
139
147
|
processing_error: [Error, Message];
|
|
148
|
+
/**
|
|
149
|
+
* Fired when requests to SQS were aborted.
|
|
150
|
+
*/
|
|
151
|
+
aborted: [];
|
|
140
152
|
/**
|
|
141
153
|
* Fired when the consumer finally stops its work.
|
|
142
154
|
*/
|
package/package.json
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sqs-consumer",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0",
|
|
4
4
|
"description": "Build SQS-based Node applications without the boilerplate",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=16.19.0"
|
|
9
|
+
},
|
|
7
10
|
"scripts": {
|
|
8
11
|
"build": "npm run clean && tsc",
|
|
9
12
|
"watch": "tsc --watch",
|
package/src/consumer.ts
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
} from '@aws-sdk/client-sqs';
|
|
18
18
|
import Debug from 'debug';
|
|
19
19
|
|
|
20
|
-
import { ConsumerOptions, TypedEventEmitter } from './types';
|
|
20
|
+
import { ConsumerOptions, TypedEventEmitter, StopOptions } from './types';
|
|
21
21
|
import { autoBind } from './bind';
|
|
22
22
|
import {
|
|
23
23
|
SQSError,
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
isConnectionError
|
|
27
27
|
} from './errors';
|
|
28
28
|
import { assertOptions, hasMessages } from './validation';
|
|
29
|
+
import { abortController } from './controllers';
|
|
29
30
|
|
|
30
31
|
const debug = Debug('sqs-consumer');
|
|
31
32
|
|
|
@@ -101,7 +102,7 @@ export class Consumer extends TypedEventEmitter {
|
|
|
101
102
|
/**
|
|
102
103
|
* Stop polling the queue for messages (pre existing requests will still be made until concluded).
|
|
103
104
|
*/
|
|
104
|
-
public stop(): void {
|
|
105
|
+
public stop(options: StopOptions): void {
|
|
105
106
|
if (this.stopped) {
|
|
106
107
|
debug('Consumer was already stopped');
|
|
107
108
|
return;
|
|
@@ -115,6 +116,14 @@ export class Consumer extends TypedEventEmitter {
|
|
|
115
116
|
this.pollingTimeoutId = undefined;
|
|
116
117
|
}
|
|
117
118
|
|
|
119
|
+
if (options?.abort) {
|
|
120
|
+
debug('Aborting SQS requests');
|
|
121
|
+
|
|
122
|
+
abortController.abort();
|
|
123
|
+
|
|
124
|
+
this.emit('aborted');
|
|
125
|
+
}
|
|
126
|
+
|
|
118
127
|
this.emit('stopped');
|
|
119
128
|
}
|
|
120
129
|
|
|
@@ -142,6 +151,13 @@ export class Consumer extends TypedEventEmitter {
|
|
|
142
151
|
}
|
|
143
152
|
}
|
|
144
153
|
|
|
154
|
+
/**
|
|
155
|
+
* A reusable options object for sqs.send that's used to avoid duplication.
|
|
156
|
+
*/
|
|
157
|
+
private sqsSendOptions = {
|
|
158
|
+
abortSignal: abortController.signal
|
|
159
|
+
};
|
|
160
|
+
|
|
145
161
|
/**
|
|
146
162
|
* Poll for new messages from SQS
|
|
147
163
|
*/
|
|
@@ -190,7 +206,10 @@ export class Consumer extends TypedEventEmitter {
|
|
|
190
206
|
params: ReceiveMessageCommandInput
|
|
191
207
|
): Promise<ReceiveMessageCommandOutput> {
|
|
192
208
|
try {
|
|
193
|
-
return await this.sqs.send(
|
|
209
|
+
return await this.sqs.send(
|
|
210
|
+
new ReceiveMessageCommand(params),
|
|
211
|
+
this.sqsSendOptions
|
|
212
|
+
);
|
|
194
213
|
} catch (err) {
|
|
195
214
|
throw toSQSError(err, `SQS receive message failed: ${err.message}`);
|
|
196
215
|
}
|
|
@@ -319,7 +338,10 @@ export class Consumer extends TypedEventEmitter {
|
|
|
319
338
|
ReceiptHandle: message.ReceiptHandle,
|
|
320
339
|
VisibilityTimeout: timeout
|
|
321
340
|
};
|
|
322
|
-
return await this.sqs.send(
|
|
341
|
+
return await this.sqs.send(
|
|
342
|
+
new ChangeMessageVisibilityCommand(input),
|
|
343
|
+
this.sqsSendOptions
|
|
344
|
+
);
|
|
323
345
|
} catch (err) {
|
|
324
346
|
this.emit(
|
|
325
347
|
'error',
|
|
@@ -348,7 +370,8 @@ export class Consumer extends TypedEventEmitter {
|
|
|
348
370
|
};
|
|
349
371
|
try {
|
|
350
372
|
return await this.sqs.send(
|
|
351
|
-
new ChangeMessageVisibilityBatchCommand(params)
|
|
373
|
+
new ChangeMessageVisibilityBatchCommand(params),
|
|
374
|
+
this.sqsSendOptions
|
|
352
375
|
);
|
|
353
376
|
} catch (err) {
|
|
354
377
|
this.emit(
|
|
@@ -426,7 +449,10 @@ export class Consumer extends TypedEventEmitter {
|
|
|
426
449
|
};
|
|
427
450
|
|
|
428
451
|
try {
|
|
429
|
-
await this.sqs.send(
|
|
452
|
+
await this.sqs.send(
|
|
453
|
+
new DeleteMessageCommand(deleteParams),
|
|
454
|
+
this.sqsSendOptions
|
|
455
|
+
);
|
|
430
456
|
} catch (err) {
|
|
431
457
|
throw toSQSError(err, `SQS delete message failed: ${err.message}`);
|
|
432
458
|
}
|
|
@@ -457,7 +483,10 @@ export class Consumer extends TypedEventEmitter {
|
|
|
457
483
|
};
|
|
458
484
|
|
|
459
485
|
try {
|
|
460
|
-
await this.sqs.send(
|
|
486
|
+
await this.sqs.send(
|
|
487
|
+
new DeleteMessageBatchCommand(deleteParams),
|
|
488
|
+
this.sqsSendOptions
|
|
489
|
+
);
|
|
461
490
|
} catch (err) {
|
|
462
491
|
throw toSQSError(err, `SQS delete message failed: ${err.message}`);
|
|
463
492
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const abortController = new AbortController();
|
package/src/types.ts
CHANGED
|
@@ -106,6 +106,15 @@ export interface ConsumerOptions {
|
|
|
106
106
|
handleMessageBatch?(messages: Message[]): Promise<Message[] | void>;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
export interface StopOptions {
|
|
110
|
+
/**
|
|
111
|
+
* Default to `false`, if you want the stop action to also abort requests to SQS
|
|
112
|
+
* set this to `true`.
|
|
113
|
+
* @defaultvalue `false`
|
|
114
|
+
*/
|
|
115
|
+
abort?: boolean;
|
|
116
|
+
}
|
|
117
|
+
|
|
109
118
|
export interface Events {
|
|
110
119
|
/**
|
|
111
120
|
* Fired after one batch of items (up to `batchSize`) has been successfully processed.
|
|
@@ -138,6 +147,10 @@ export interface Events {
|
|
|
138
147
|
* Fired when an error occurs processing the message.
|
|
139
148
|
*/
|
|
140
149
|
processing_error: [Error, Message];
|
|
150
|
+
/**
|
|
151
|
+
* Fired when requests to SQS were aborted.
|
|
152
|
+
*/
|
|
153
|
+
aborted: [];
|
|
141
154
|
/**
|
|
142
155
|
* Fired when the consumer finally stops its work.
|
|
143
156
|
*/
|