ac-sqs 3.0.0 → 3.1.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/CHANGELOG.md +19 -0
- package/README.md +4 -1
- package/index.js +96 -5
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
# [3.1.0](https://github.com/admiralcloud/ac-sqs/compare/v3.0.0..v3.1.0) (2025-04-12 08:11:38)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Feature
|
|
6
|
+
|
|
7
|
+
* **App:** Add visibilityTimeout management | MP | [ccdd4d0230fc98a5e1aa8531a9939ef2457b614a](https://github.com/admiralcloud/ac-sqs/commit/ccdd4d0230fc98a5e1aa8531a9939ef2457b614a)
|
|
8
|
+
It is now possible to automatically extend visibility for messages. Just set visibilityTimeout in list config
|
|
9
|
+
Related issues: [admiralcloud/ac-sqs#1](https://github.com/admiralcloud/ac-sqs/issues/1) [admiralcloud/ac-api-server#340](https://github.com/admiralcloud/ac-api-server/issues/340)
|
|
10
|
+
### Documentation
|
|
11
|
+
|
|
12
|
+
* **App:** Added visibilityTimeout management | MP | [4c6e916b0056c894dcac5cb58fa48166de769de4](https://github.com/admiralcloud/ac-sqs/commit/4c6e916b0056c894dcac5cb58fa48166de769de4)
|
|
13
|
+
Added visibilityTimeout management
|
|
14
|
+
Related issues: [admiralcloud/ac-sqs#1](https://github.com/admiralcloud/ac-sqs/issues/1) [admiralcloud/ac-api-server#340](https://github.com/admiralcloud/ac-api-server/issues/340)
|
|
15
|
+
### Chores
|
|
16
|
+
|
|
17
|
+
* **App:** Updated packages | MP | [c2f533d3bd7bb0d9917d9815e46ef6e8ab5c79d2](https://github.com/admiralcloud/ac-sqs/commit/c2f533d3bd7bb0d9917d9815e46ef6e8ab5c79d2)
|
|
18
|
+
Updated packages
|
|
19
|
+
Related issues: [admiralcloud/ac-sqs#1](https://github.com/admiralcloud/ac-sqs/issues/1) [admiralcloud/ac-api-server#340](https://github.com/admiralcloud/ac-api-server/issues/340)
|
|
1
20
|
<a name="3.0.0"></a>
|
|
2
21
|
|
|
3
22
|
# [3.0.0](https://github.com/admiralcloud/ac-sqs/compare/v2.0.8..v3.0.0) (2024-10-17 15:51:06)
|
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ The ***account*** id of your AWS account. This is required
|
|
|
33
33
|
Array of AWS SQS lists that will be used by this function. Every item in the list must be an object with the following properties:
|
|
34
34
|
+ name -> the name of the list in AWS SQS. See below for more info.
|
|
35
35
|
+ batchSize -> number of messages to fetch per call. Max 10, defaults to 1
|
|
36
|
-
+ visibilityTimeout -> see AWS SQS for details, defaults to 30
|
|
36
|
+
+ visibilityTimeout -> see AWS SQS for details, defaults to 30. If set, visibilityTimeout management is activated
|
|
37
37
|
+ waitTime -> see AWS SQS for details, defaults to 20
|
|
38
38
|
+ fifo -> set to true, if this is a fifo list
|
|
39
39
|
+ localPrefix -> set your local prefix. See below for more info
|
|
@@ -55,6 +55,9 @@ useS3: {
|
|
|
55
55
|
}
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
+
**Visibility Timeout Management**
|
|
59
|
+
If you set list config parameter visibilityTimeout, the automatic visibilityTimeout management will be activated. It will make sure that visibilityTimeout for messages is automatically extended.
|
|
60
|
+
|
|
58
61
|
Make sure your function can read, write and delete messages in the bucket.
|
|
59
62
|
|
|
60
63
|
## sendSQSMessage
|
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const _ = require('lodash')
|
|
2
2
|
const { v4: uuidV4 } = require('uuid')
|
|
3
3
|
|
|
4
|
-
const { SQSClient, SendMessageCommand, ReceiveMessageCommand, DeleteMessageBatchCommand, GetQueueAttributesCommand } = require('@aws-sdk/client-sqs')
|
|
4
|
+
const { SQSClient, SendMessageCommand, ReceiveMessageCommand, DeleteMessageBatchCommand, GetQueueAttributesCommand, ChangeMessageVisibilityCommand } = require('@aws-sdk/client-sqs')
|
|
5
5
|
const { S3Client, GetObjectCommand, PutObjectCommand, DeleteObjectsCommand } = require("@aws-sdk/client-s3")
|
|
6
6
|
|
|
7
7
|
|
|
@@ -12,6 +12,7 @@ class ACSQS {
|
|
|
12
12
|
this.availableLists = availableLists
|
|
13
13
|
this.logger = logger
|
|
14
14
|
this.throwError = throwError
|
|
15
|
+
this.visibilityTimer = {}
|
|
15
16
|
|
|
16
17
|
const awsConfig = {
|
|
17
18
|
region,
|
|
@@ -109,13 +110,71 @@ class ACSQS {
|
|
|
109
110
|
}
|
|
110
111
|
}
|
|
111
112
|
|
|
113
|
+
async extendVisibility({ name, message }) {
|
|
114
|
+
const config = _.find(this.availableLists, { name })
|
|
115
|
+
if (!config) {
|
|
116
|
+
this.logger.error('AWS | extendVisibility | configurationMissing | %s', name)
|
|
117
|
+
throw new Error('configurationForListMissing')
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const visibilityTimeout = _.get(config, 'visibilityTimeout', 15)
|
|
121
|
+
const maxVisibilityExtensions = _.get(config, 'maxVisibilityExtensions', 12) // max number of times the extension can me made (12 x 15s = 3min)
|
|
122
|
+
|
|
123
|
+
const { MessageId: messageId, ReceiptHandle: receiptHandle } = message
|
|
124
|
+
|
|
125
|
+
// Check if we've reached maximum extensions
|
|
126
|
+
if (this.visibilityTimer[messageId] && this.visibilityTimer[messageId].visibilityExtensionCount >= maxVisibilityExtensions) {
|
|
127
|
+
this.logger.warn('ACSQS | extendVisibility | %s | M %s | Max extensions reached | %s | %j', name, messageId, maxVisibilityExtensions, message)
|
|
128
|
+
this.deleteVisibilityTimer({ messageId })
|
|
129
|
+
return
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Track extension count
|
|
133
|
+
if (this.visibilityTimer[messageId]) {
|
|
134
|
+
this.visibilityTimer[messageId].visibilityExtensionCount++
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const sqsParams = {
|
|
138
|
+
QueueUrl: await this.getQueueUrl(config),
|
|
139
|
+
ReceiptHandle: receiptHandle,
|
|
140
|
+
VisibilityTimeout: visibilityTimeout
|
|
141
|
+
}
|
|
142
|
+
const command = new ChangeMessageVisibilityCommand(sqsParams)
|
|
143
|
+
try {
|
|
144
|
+
const response = await this.sqs.send(command)
|
|
145
|
+
if (config.debug) {
|
|
146
|
+
const visibilityExtensionCount = this.visibilityTimer[messageId] ? this.visibilityTimer[messageId].visibilityExtensionCount : 0
|
|
147
|
+
this.logger.debug('ACSQS | extendVisibility | %s | M %s | %ss | %s | %j', name, messageId, visibilityTimeout, visibilityExtensionCount, message)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return response
|
|
151
|
+
}
|
|
152
|
+
catch(e) {
|
|
153
|
+
this.logger.error('ACSQS | extendVisibility | %s | %s', name, e?.message)
|
|
154
|
+
this.deleteVisibilityTimer({ messageId })
|
|
155
|
+
if (this.throwError || throwError) throw e
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
deleteVisibilityTimer({ messageId }) {
|
|
160
|
+
if (this.visibilityTimer[messageId]) {
|
|
161
|
+
clearTimeout(this.visibilityTimer[messageId].timer)
|
|
162
|
+
const self = this
|
|
163
|
+
setTimeout(() => {
|
|
164
|
+
delete self.visibilityTimer[messageId]
|
|
165
|
+
}, 1000)
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
112
169
|
async receiveSQSMessages({ name, throwError }) {
|
|
113
170
|
const config = _.find(this.availableLists, { name })
|
|
114
171
|
if (!config) {
|
|
115
|
-
this.logger.error('
|
|
172
|
+
this.logger.error('ACSQS | receiveSQSMessage | configurationMissing | %s', name)
|
|
116
173
|
throw new Error('configurationForListMissing')
|
|
117
174
|
}
|
|
118
|
-
|
|
175
|
+
const visibilityTimeout = _.get(config, 'visibilityTimeout') // if set, will activate visibilityTimeout management
|
|
176
|
+
|
|
177
|
+
const sqsParams = {
|
|
119
178
|
QueueUrl: await this.getQueueUrl(config),
|
|
120
179
|
MaxNumberOfMessages: _.get(config, 'batchSize', 10),
|
|
121
180
|
VisibilityTimeout: _.get(config, 'visibilityTimeout', 30),
|
|
@@ -126,7 +185,9 @@ class ACSQS {
|
|
|
126
185
|
try {
|
|
127
186
|
const result = await this.sqs.send(command)
|
|
128
187
|
if (!_.size(result.Messages)) return
|
|
129
|
-
|
|
188
|
+
|
|
189
|
+
// Benutze Arrow-Funktion, um `this` beizubehalten
|
|
190
|
+
const messages = await Promise.all(result.Messages.map(async (message) => {
|
|
130
191
|
if (message.Body.startsWith('s3:')) {
|
|
131
192
|
const key = message.Body.replace('s3:', '')
|
|
132
193
|
try {
|
|
@@ -135,9 +196,29 @@ class ACSQS {
|
|
|
135
196
|
message.s3key = key
|
|
136
197
|
}
|
|
137
198
|
catch(e) {
|
|
138
|
-
this.logger.error('
|
|
199
|
+
this.logger.error('ACSQS | receiveSQSMessages | s3KeyInvalid | %s', name, key)
|
|
139
200
|
}
|
|
140
201
|
}
|
|
202
|
+
|
|
203
|
+
if (visibilityTimeout > 0) {
|
|
204
|
+
// start visibility timer that automatically extends visibility of the message if required
|
|
205
|
+
const { MessageId: messageId } = message
|
|
206
|
+
const timeoutMs = Math.floor(visibilityTimeout * 0.8 * 1000)
|
|
207
|
+
const self = this // `this` als lokale Variable speichern
|
|
208
|
+
|
|
209
|
+
this.visibilityTimer[messageId] = {
|
|
210
|
+
// Arrow-Funktion für setInterval damit `this` erhalten bleibt,
|
|
211
|
+
// oder verwende die lokale Variable `self`
|
|
212
|
+
timer: setInterval(() => {
|
|
213
|
+
this.extendVisibility({ name, message })
|
|
214
|
+
.catch(e => {
|
|
215
|
+
this.logger.error('ACSQS | AutoExtendVisibility | Failed %s', e.message)
|
|
216
|
+
})
|
|
217
|
+
}, timeoutMs),
|
|
218
|
+
visibilityExtensionCount: 0
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
141
222
|
return message
|
|
142
223
|
}))
|
|
143
224
|
return messages
|
|
@@ -156,6 +237,11 @@ class ACSQS {
|
|
|
156
237
|
throw new Error('configurationForListMissing')
|
|
157
238
|
}
|
|
158
239
|
|
|
240
|
+
if (!_.size(items)) {
|
|
241
|
+
this.logger.error('AWS | deleteSQSMessage | %s | noItemsToDelete', name)
|
|
242
|
+
return
|
|
243
|
+
}
|
|
244
|
+
|
|
159
245
|
const entries = []
|
|
160
246
|
const s3keys = []
|
|
161
247
|
for (const item of items) {
|
|
@@ -163,8 +249,13 @@ class ACSQS {
|
|
|
163
249
|
if (item.s3key) {
|
|
164
250
|
s3keys.push({ Key: item.s3key })
|
|
165
251
|
}
|
|
252
|
+
const messageId = item.Id
|
|
253
|
+
if (this.visibilityTimer[messageId]) {
|
|
254
|
+
this.deleteVisibilityTimer({ messageId })
|
|
255
|
+
}
|
|
166
256
|
}
|
|
167
257
|
|
|
258
|
+
|
|
168
259
|
let sqsParams = {
|
|
169
260
|
QueueUrl: await this.getQueueUrl(config),
|
|
170
261
|
Entries: entries
|
package/package.json
CHANGED
|
@@ -3,18 +3,18 @@
|
|
|
3
3
|
"author": "Mark Poepping (https://www.admiralcloud.com)",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": "admiralcloud/ac-sqs",
|
|
6
|
-
"version": "3.
|
|
6
|
+
"version": "3.1.0",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@aws-sdk/client-s3": "^3.
|
|
9
|
-
"@aws-sdk/client-sqs": "^3.
|
|
8
|
+
"@aws-sdk/client-s3": "^3.787.0",
|
|
9
|
+
"@aws-sdk/client-sqs": "^3.787.0",
|
|
10
10
|
"lodash": "^4.17.21",
|
|
11
|
-
"uuid": "^
|
|
11
|
+
"uuid": "^11.1.0"
|
|
12
12
|
},
|
|
13
13
|
"devDependencies": {
|
|
14
|
-
"ac-semantic-release": "^0.4.
|
|
14
|
+
"ac-semantic-release": "^0.4.5",
|
|
15
15
|
"chai": "^4.5.0",
|
|
16
|
-
"eslint": "^9.
|
|
17
|
-
"mocha": "^
|
|
16
|
+
"eslint": "^9.24.0",
|
|
17
|
+
"mocha": "^11.1.0"
|
|
18
18
|
},
|
|
19
19
|
"scripts": {
|
|
20
20
|
"test": "mocha --reporter spec"
|