@eyevinn/player-analytics-shared 0.9.3 → 0.10.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/adapters/queue/BeanstalkdAdapter.ts +25 -0
- package/adapters/queue/RedisAdapter.ts +25 -0
- package/adapters/queue/SqsQueueAdapter.ts +67 -0
- package/build/adapters/queue/BeanstalkdAdapter.d.ts +1 -0
- package/build/adapters/queue/BeanstalkdAdapter.js +26 -0
- package/build/adapters/queue/BeanstalkdAdapter.js.map +1 -1
- package/build/adapters/queue/RedisAdapter.d.ts +1 -0
- package/build/adapters/queue/RedisAdapter.js +26 -0
- package/build/adapters/queue/RedisAdapter.js.map +1 -1
- package/build/adapters/queue/SqsQueueAdapter.d.ts +2 -0
- package/build/adapters/queue/SqsQueueAdapter.js +54 -0
- package/build/adapters/queue/SqsQueueAdapter.js.map +1 -1
- package/build/types/queue.d.ts +1 -0
- package/build/types/queue.js.map +1 -1
- package/package.json +1 -1
- package/spec/adapters/SqsQueueAdapter.spec.ts +105 -0
- package/types/queue.ts +1 -0
|
@@ -34,6 +34,31 @@ export class BeanstalkdAdapter implements AbstractQueueAdapter {
|
|
|
34
34
|
return result;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
async removeFromQueueBatch(messages: Record<string, any>[]): Promise<Object> {
|
|
38
|
+
const results: { successful: any[]; failed: any[] } = {
|
|
39
|
+
successful: [],
|
|
40
|
+
failed: [],
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
for (const message of messages) {
|
|
44
|
+
try {
|
|
45
|
+
const success = await this.removeFromQueue(message);
|
|
46
|
+
if (success) {
|
|
47
|
+
results.successful.push({ id: message.id });
|
|
48
|
+
} else {
|
|
49
|
+
results.failed.push({ id: message.id, reason: 'delete failed' });
|
|
50
|
+
}
|
|
51
|
+
} catch (err) {
|
|
52
|
+
results.failed.push({
|
|
53
|
+
id: message.id,
|
|
54
|
+
reason: err instanceof Error ? err.message : 'Unknown error',
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return results;
|
|
60
|
+
}
|
|
61
|
+
|
|
37
62
|
getEventJSONsFromMessages(body: any[]): Object[] {
|
|
38
63
|
this.logger.warn("Method not implemented.");
|
|
39
64
|
return body;
|
|
@@ -27,6 +27,31 @@ export class RedisAdapter implements AbstractQueueAdapter {
|
|
|
27
27
|
return result === 'completed';
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
async removeFromQueueBatch(messages: Record<string, any>[]): Promise<Object> {
|
|
31
|
+
const results: { successful: any[]; failed: any[] } = {
|
|
32
|
+
successful: [],
|
|
33
|
+
failed: [],
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
for (const message of messages) {
|
|
37
|
+
try {
|
|
38
|
+
const success = await this.removeFromQueue(message);
|
|
39
|
+
if (success) {
|
|
40
|
+
results.successful.push({ id: message.id });
|
|
41
|
+
} else {
|
|
42
|
+
results.failed.push({ id: message.id, reason: 'not completed' });
|
|
43
|
+
}
|
|
44
|
+
} catch (err) {
|
|
45
|
+
results.failed.push({
|
|
46
|
+
id: message.id,
|
|
47
|
+
reason: err instanceof Error ? err.message : 'Unknown error',
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return results;
|
|
53
|
+
}
|
|
54
|
+
|
|
30
55
|
getEventJSONsFromMessages(body: any[]): Object[] {
|
|
31
56
|
this.logger.warn("Method not implemented.");
|
|
32
57
|
return body;
|
|
@@ -5,6 +5,9 @@ import {
|
|
|
5
5
|
ReceiveMessageCommandInput,
|
|
6
6
|
ReceiveMessageCommand,
|
|
7
7
|
DeleteMessageCommandInput,
|
|
8
|
+
DeleteMessageBatchCommand,
|
|
9
|
+
DeleteMessageBatchCommandInput,
|
|
10
|
+
DeleteMessageBatchRequestEntry,
|
|
8
11
|
Message,
|
|
9
12
|
DeleteMessageCommand,
|
|
10
13
|
paginateListQueues,
|
|
@@ -18,6 +21,7 @@ import { Agent as HttpsAgent } from 'https';
|
|
|
18
21
|
|
|
19
22
|
export interface SqsQueueAdapterOptions {
|
|
20
23
|
maxSockets?: number;
|
|
24
|
+
skipQueueExistsCheck?: boolean;
|
|
21
25
|
}
|
|
22
26
|
|
|
23
27
|
export class SqsQueueAdapter implements AbstractQueueAdapter {
|
|
@@ -29,6 +33,9 @@ export class SqsQueueAdapter implements AbstractQueueAdapter {
|
|
|
29
33
|
|
|
30
34
|
constructor(logger: winston.Logger, options?: SqsQueueAdapterOptions) {
|
|
31
35
|
this.logger = logger;
|
|
36
|
+
if (options?.skipQueueExistsCheck) {
|
|
37
|
+
this.queueExists = true;
|
|
38
|
+
}
|
|
32
39
|
let region: any;
|
|
33
40
|
if ('QUEUE_REGION' in process.env) {
|
|
34
41
|
region = process.env.QUEUE_REGION;
|
|
@@ -251,6 +258,66 @@ export class SqsQueueAdapter implements AbstractQueueAdapter {
|
|
|
251
258
|
}
|
|
252
259
|
}
|
|
253
260
|
|
|
261
|
+
async removeFromQueueBatch(messages: Message[]): Promise<any> {
|
|
262
|
+
if (process.env.SQS_QUEUE_URL === 'undefined') {
|
|
263
|
+
return { message: 'SQS_QUEUE_URL is undefined' };
|
|
264
|
+
}
|
|
265
|
+
if (!messages || messages.length === 0) {
|
|
266
|
+
return { successful: [], failed: [] };
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const results: { successful: any[]; failed: any[] } = {
|
|
270
|
+
successful: [],
|
|
271
|
+
failed: [],
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
// SQS allows max 10 messages per batch
|
|
275
|
+
const batchSize = 10;
|
|
276
|
+
for (let i = 0; i < messages.length; i += batchSize) {
|
|
277
|
+
const batch = messages.slice(i, i + batchSize);
|
|
278
|
+
const entries: DeleteMessageBatchRequestEntry[] = batch.map(
|
|
279
|
+
(msg, index) => ({
|
|
280
|
+
Id: `${i + index}`,
|
|
281
|
+
ReceiptHandle: msg.ReceiptHandle!,
|
|
282
|
+
})
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
const params: DeleteMessageBatchCommandInput = {
|
|
286
|
+
QueueUrl: process.env.SQS_QUEUE_URL,
|
|
287
|
+
Entries: entries,
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
const deleteMessageBatchCommand = new DeleteMessageBatchCommand(params);
|
|
291
|
+
try {
|
|
292
|
+
const batchResult = await this.client.send(deleteMessageBatchCommand);
|
|
293
|
+
this.logger.debug(
|
|
294
|
+
`Batch delete response from SQS: ${JSON.stringify(batchResult)}`
|
|
295
|
+
);
|
|
296
|
+
if (batchResult.Successful) {
|
|
297
|
+
results.successful.push(...batchResult.Successful);
|
|
298
|
+
}
|
|
299
|
+
if (batchResult.Failed) {
|
|
300
|
+
results.failed.push(...batchResult.Failed);
|
|
301
|
+
}
|
|
302
|
+
} catch (err) {
|
|
303
|
+
this.logger.error(`Batch delete error: ${JSON.stringify(err)}`);
|
|
304
|
+
// Mark all messages in this batch as failed
|
|
305
|
+
entries.forEach((entry) => {
|
|
306
|
+
results.failed.push({
|
|
307
|
+
Id: entry.Id,
|
|
308
|
+
Code: 'BatchError',
|
|
309
|
+
Message: err instanceof Error ? err.message : 'Unknown error',
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
this.logger.debug(
|
|
316
|
+
`Batch remove complete: ${results.successful.length} successful, ${results.failed.length} failed`
|
|
317
|
+
);
|
|
318
|
+
return results;
|
|
319
|
+
}
|
|
320
|
+
|
|
254
321
|
getEventJSONsFromMessages(messages: Message[]): any[] {
|
|
255
322
|
return messages.map((item) => (item.Body ? JSON.parse(item.Body) : {}));
|
|
256
323
|
}
|
|
@@ -9,5 +9,6 @@ export declare class BeanstalkdAdapter implements AbstractQueueAdapter {
|
|
|
9
9
|
pushToQueue(body: Object): Promise<Object>;
|
|
10
10
|
pullFromQueue(): Promise<Object>;
|
|
11
11
|
removeFromQueue(body: Record<string, any>): Promise<boolean>;
|
|
12
|
+
removeFromQueueBatch(messages: Record<string, any>[]): Promise<Object>;
|
|
12
13
|
getEventJSONsFromMessages(body: any[]): Object[];
|
|
13
14
|
}
|
|
@@ -46,6 +46,32 @@ class BeanstalkdAdapter {
|
|
|
46
46
|
return result;
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
|
+
removeFromQueueBatch(messages) {
|
|
50
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
const results = {
|
|
52
|
+
successful: [],
|
|
53
|
+
failed: [],
|
|
54
|
+
};
|
|
55
|
+
for (const message of messages) {
|
|
56
|
+
try {
|
|
57
|
+
const success = yield this.removeFromQueue(message);
|
|
58
|
+
if (success) {
|
|
59
|
+
results.successful.push({ id: message.id });
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
results.failed.push({ id: message.id, reason: 'delete failed' });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
results.failed.push({
|
|
67
|
+
id: message.id,
|
|
68
|
+
reason: err instanceof Error ? err.message : 'Unknown error',
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return results;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
49
75
|
getEventJSONsFromMessages(body) {
|
|
50
76
|
this.logger.warn("Method not implemented.");
|
|
51
77
|
return body;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BeanstalkdAdapter.js","sourceRoot":"","sources":["../../../adapters/queue/BeanstalkdAdapter.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,mDAAwC;AAIxC,MAAa,iBAAiB;IAI5B,YAAY,MAAsB;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,IAAI,uBAAM,EAAE,CAAC;IAC7B,CAAC;IAEa,OAAO;;YACnB,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAC9B,CAAC;KAAA;IAEK,WAAW,CAAC,IAAY;;YAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW;gBAAE,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YACnD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC3C,OAAO,MAAM,CAAC;QAChB,CAAC;KAAA;IAEK,aAAa;;YACjB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW;gBAAE,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YACnD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;YACpD,OAAO,GAAG,IAAI,EAAE,CAAC;QACnB,CAAC;KAAA;IAEK,eAAe,CAAC,IAAyB;;YAC7C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW;gBAAE,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YACnD,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC;YACtB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC/C,OAAO,MAAM,CAAC;QAChB,CAAC;KAAA;IAED,yBAAyB,CAAC,IAAW;QACnC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"BeanstalkdAdapter.js","sourceRoot":"","sources":["../../../adapters/queue/BeanstalkdAdapter.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,mDAAwC;AAIxC,MAAa,iBAAiB;IAI5B,YAAY,MAAsB;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,IAAI,uBAAM,EAAE,CAAC;IAC7B,CAAC;IAEa,OAAO;;YACnB,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAC9B,CAAC;KAAA;IAEK,WAAW,CAAC,IAAY;;YAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW;gBAAE,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YACnD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC3C,OAAO,MAAM,CAAC;QAChB,CAAC;KAAA;IAEK,aAAa;;YACjB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW;gBAAE,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YACnD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;YACpD,OAAO,GAAG,IAAI,EAAE,CAAC;QACnB,CAAC;KAAA;IAEK,eAAe,CAAC,IAAyB;;YAC7C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW;gBAAE,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YACnD,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC;YACtB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC/C,OAAO,MAAM,CAAC;QAChB,CAAC;KAAA;IAEK,oBAAoB,CAAC,QAA+B;;YACxD,MAAM,OAAO,GAAyC;gBACpD,UAAU,EAAE,EAAE;gBACd,MAAM,EAAE,EAAE;aACX,CAAC;YAEF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;gBAC9B,IAAI;oBACF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;oBACpD,IAAI,OAAO,EAAE;wBACX,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;qBAC7C;yBAAM;wBACL,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC;qBAClE;iBACF;gBAAC,OAAO,GAAG,EAAE;oBACZ,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;wBAClB,EAAE,EAAE,OAAO,CAAC,EAAE;wBACd,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;qBAC7D,CAAC,CAAC;iBACJ;aACF;YAED,OAAO,OAAO,CAAC;QACjB,CAAC;KAAA;IAED,yBAAyB,CAAC,IAAW;QACnC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AA7DD,8CA6DC"}
|
|
@@ -8,5 +8,6 @@ export declare class RedisAdapter implements AbstractQueueAdapter {
|
|
|
8
8
|
pushToQueue(body: Object): Promise<Object>;
|
|
9
9
|
pullFromQueue(): Promise<Object>;
|
|
10
10
|
removeFromQueue(body: Record<string, any>): Promise<boolean>;
|
|
11
|
+
removeFromQueueBatch(messages: Record<string, any>[]): Promise<Object>;
|
|
11
12
|
getEventJSONsFromMessages(body: any[]): Object[];
|
|
12
13
|
}
|
|
@@ -35,6 +35,32 @@ class RedisAdapter {
|
|
|
35
35
|
return result === 'completed';
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
|
+
removeFromQueueBatch(messages) {
|
|
39
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
40
|
+
const results = {
|
|
41
|
+
successful: [],
|
|
42
|
+
failed: [],
|
|
43
|
+
};
|
|
44
|
+
for (const message of messages) {
|
|
45
|
+
try {
|
|
46
|
+
const success = yield this.removeFromQueue(message);
|
|
47
|
+
if (success) {
|
|
48
|
+
results.successful.push({ id: message.id });
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
results.failed.push({ id: message.id, reason: 'not completed' });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
results.failed.push({
|
|
56
|
+
id: message.id,
|
|
57
|
+
reason: err instanceof Error ? err.message : 'Unknown error',
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return results;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
38
64
|
getEventJSONsFromMessages(body) {
|
|
39
65
|
this.logger.warn("Method not implemented.");
|
|
40
66
|
return body;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RedisAdapter.js","sourceRoot":"","sources":["../../../adapters/queue/RedisAdapter.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,mDAAoD;AAIpD,MAAa,YAAY;IAIvB,YAAY,MAAsB;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;IACrC,CAAC;IAEK,WAAW,CAAC,IAAY;;YAC5B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACrD,OAAO,MAAM,CAAC;QAChB,CAAC;KAAA;IAEK,aAAa;;YACjB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;YACpC,OAAO,GAAG,IAAI,EAAE,CAAC;QACnB,CAAC;KAAA;IAEK,eAAe,CAAC,IAAyB;;YAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC;YACtB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAClD,OAAO,MAAM,KAAK,WAAW,CAAC;QAChC,CAAC;KAAA;IAED,yBAAyB,CAAC,IAAW;QACnC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"RedisAdapter.js","sourceRoot":"","sources":["../../../adapters/queue/RedisAdapter.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,mDAAoD;AAIpD,MAAa,YAAY;IAIvB,YAAY,MAAsB;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;IACrC,CAAC;IAEK,WAAW,CAAC,IAAY;;YAC5B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACrD,OAAO,MAAM,CAAC;QAChB,CAAC;KAAA;IAEK,aAAa;;YACjB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;YACpC,OAAO,GAAG,IAAI,EAAE,CAAC;QACnB,CAAC;KAAA;IAEK,eAAe,CAAC,IAAyB;;YAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC;YACtB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAClD,OAAO,MAAM,KAAK,WAAW,CAAC;QAChC,CAAC;KAAA;IAEK,oBAAoB,CAAC,QAA+B;;YACxD,MAAM,OAAO,GAAyC;gBACpD,UAAU,EAAE,EAAE;gBACd,MAAM,EAAE,EAAE;aACX,CAAC;YAEF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;gBAC9B,IAAI;oBACF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;oBACpD,IAAI,OAAO,EAAE;wBACX,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;qBAC7C;yBAAM;wBACL,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC;qBAClE;iBACF;gBAAC,OAAO,GAAG,EAAE;oBACZ,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;wBAClB,EAAE,EAAE,OAAO,CAAC,EAAE;wBACd,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;qBAC7D,CAAC,CAAC;iBACJ;aACF;YAED,OAAO,OAAO,CAAC;QACjB,CAAC;KAAA;IAED,yBAAyB,CAAC,IAAW;QACnC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAtDD,oCAsDC"}
|
|
@@ -3,6 +3,7 @@ import { AbstractQueueAdapter } from '../../types/interfaces';
|
|
|
3
3
|
import winston from 'winston';
|
|
4
4
|
export interface SqsQueueAdapterOptions {
|
|
5
5
|
maxSockets?: number;
|
|
6
|
+
skipQueueExistsCheck?: boolean;
|
|
6
7
|
}
|
|
7
8
|
export declare class SqsQueueAdapter implements AbstractQueueAdapter {
|
|
8
9
|
logger: winston.Logger;
|
|
@@ -17,5 +18,6 @@ export declare class SqsQueueAdapter implements AbstractQueueAdapter {
|
|
|
17
18
|
pushToQueue(event: Object): Promise<any>;
|
|
18
19
|
pullFromQueue(): Promise<any>;
|
|
19
20
|
removeFromQueue(queueMsg: Message): Promise<any>;
|
|
21
|
+
removeFromQueueBatch(messages: Message[]): Promise<any>;
|
|
20
22
|
getEventJSONsFromMessages(messages: Message[]): any[];
|
|
21
23
|
}
|
|
@@ -26,6 +26,9 @@ class SqsQueueAdapter {
|
|
|
26
26
|
this.queueExists = false;
|
|
27
27
|
this.httpAgent = {};
|
|
28
28
|
this.logger = logger;
|
|
29
|
+
if (options === null || options === void 0 ? void 0 : options.skipQueueExistsCheck) {
|
|
30
|
+
this.queueExists = true;
|
|
31
|
+
}
|
|
29
32
|
let region;
|
|
30
33
|
if ('QUEUE_REGION' in process.env) {
|
|
31
34
|
region = process.env.QUEUE_REGION;
|
|
@@ -242,6 +245,57 @@ class SqsQueueAdapter {
|
|
|
242
245
|
}
|
|
243
246
|
});
|
|
244
247
|
}
|
|
248
|
+
removeFromQueueBatch(messages) {
|
|
249
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
250
|
+
if (process.env.SQS_QUEUE_URL === 'undefined') {
|
|
251
|
+
return { message: 'SQS_QUEUE_URL is undefined' };
|
|
252
|
+
}
|
|
253
|
+
if (!messages || messages.length === 0) {
|
|
254
|
+
return { successful: [], failed: [] };
|
|
255
|
+
}
|
|
256
|
+
const results = {
|
|
257
|
+
successful: [],
|
|
258
|
+
failed: [],
|
|
259
|
+
};
|
|
260
|
+
// SQS allows max 10 messages per batch
|
|
261
|
+
const batchSize = 10;
|
|
262
|
+
for (let i = 0; i < messages.length; i += batchSize) {
|
|
263
|
+
const batch = messages.slice(i, i + batchSize);
|
|
264
|
+
const entries = batch.map((msg, index) => ({
|
|
265
|
+
Id: `${i + index}`,
|
|
266
|
+
ReceiptHandle: msg.ReceiptHandle,
|
|
267
|
+
}));
|
|
268
|
+
const params = {
|
|
269
|
+
QueueUrl: process.env.SQS_QUEUE_URL,
|
|
270
|
+
Entries: entries,
|
|
271
|
+
};
|
|
272
|
+
const deleteMessageBatchCommand = new client_sqs_1.DeleteMessageBatchCommand(params);
|
|
273
|
+
try {
|
|
274
|
+
const batchResult = yield this.client.send(deleteMessageBatchCommand);
|
|
275
|
+
this.logger.debug(`Batch delete response from SQS: ${JSON.stringify(batchResult)}`);
|
|
276
|
+
if (batchResult.Successful) {
|
|
277
|
+
results.successful.push(...batchResult.Successful);
|
|
278
|
+
}
|
|
279
|
+
if (batchResult.Failed) {
|
|
280
|
+
results.failed.push(...batchResult.Failed);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
catch (err) {
|
|
284
|
+
this.logger.error(`Batch delete error: ${JSON.stringify(err)}`);
|
|
285
|
+
// Mark all messages in this batch as failed
|
|
286
|
+
entries.forEach((entry) => {
|
|
287
|
+
results.failed.push({
|
|
288
|
+
Id: entry.Id,
|
|
289
|
+
Code: 'BatchError',
|
|
290
|
+
Message: err instanceof Error ? err.message : 'Unknown error',
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
this.logger.debug(`Batch remove complete: ${results.successful.length} successful, ${results.failed.length} failed`);
|
|
296
|
+
return results;
|
|
297
|
+
});
|
|
298
|
+
}
|
|
245
299
|
getEventJSONsFromMessages(messages) {
|
|
246
300
|
return messages.map((item) => (item.Body ? JSON.parse(item.Body) : {}));
|
|
247
301
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqsQueueAdapter.js","sourceRoot":"","sources":["../../../adapters/queue/SqsQueueAdapter.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"SqsQueueAdapter.js","sourceRoot":"","sources":["../../../adapters/queue/SqsQueueAdapter.ts"],"names":[],"mappings":"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"}
|
package/build/types/queue.d.ts
CHANGED
|
@@ -11,5 +11,6 @@ export declare abstract class AbstractQueueAdapter {
|
|
|
11
11
|
abstract pushToQueue(body: Object): Promise<Object>;
|
|
12
12
|
abstract pullFromQueue(): Promise<Object>;
|
|
13
13
|
abstract removeFromQueue(body: Object): Promise<Object>;
|
|
14
|
+
abstract removeFromQueueBatch(messages: Object[]): Promise<Object>;
|
|
14
15
|
abstract getEventJSONsFromMessages(body: any[]): Object[];
|
|
15
16
|
}
|
package/build/types/queue.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../types/queue.ts"],"names":[],"mappings":";;;AASA,MAAsB,oBAAoB;
|
|
1
|
+
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../types/queue.ts"],"names":[],"mappings":";;;AASA,MAAsB,oBAAoB;CAQzC;AARD,oDAQC"}
|
package/package.json
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DeleteMessageCommand,
|
|
3
|
+
DeleteMessageBatchCommand,
|
|
3
4
|
Message,
|
|
4
5
|
ReceiveMessageCommand,
|
|
5
6
|
SendMessageCommand,
|
|
@@ -49,6 +50,23 @@ describe('SQS Queue Adapter', () => {
|
|
|
49
50
|
expect(adapter.client).toBeDefined();
|
|
50
51
|
});
|
|
51
52
|
|
|
53
|
+
it('should skip queue exists check when skipQueueExistsCheck option is set', async () => {
|
|
54
|
+
const sqsResp = { MessageId: '12345678-4444-5555-6666-111122223333' };
|
|
55
|
+
const adapter = new SqsQueueAdapter(Logger, { skipQueueExistsCheck: true });
|
|
56
|
+
expect(adapter.queueExists).toBe(true);
|
|
57
|
+
const event = {
|
|
58
|
+
event: 'loading',
|
|
59
|
+
timestamp: 0,
|
|
60
|
+
playhead: 0,
|
|
61
|
+
duration: 0,
|
|
62
|
+
};
|
|
63
|
+
const checkQueueExistsSpy = spyOn(adapter as any, 'checkQueueExists');
|
|
64
|
+
sqsMock.on(SendMessageCommand).resolves(sqsResp);
|
|
65
|
+
const result = await adapter.pushToQueue(event);
|
|
66
|
+
expect(result).toEqual(sqsResp);
|
|
67
|
+
expect(checkQueueExistsSpy).not.toHaveBeenCalled();
|
|
68
|
+
});
|
|
69
|
+
|
|
52
70
|
it('should push to queue if QUEUE_REGION env is set and AWS_REGION is undefined', async () => {
|
|
53
71
|
process.env.QUEUE_REGION = 'eu-north-1';
|
|
54
72
|
process.env.AWS_REGION = undefined;
|
|
@@ -160,4 +178,91 @@ describe('SQS Queue Adapter', () => {
|
|
|
160
178
|
expect(readResult.toString()).toEqual(errMsg.Code);
|
|
161
179
|
expect(removeResult.toString()).toEqual(errMsg.Code);
|
|
162
180
|
});
|
|
181
|
+
|
|
182
|
+
it('should batch remove messages from queue', async () => {
|
|
183
|
+
const batchResp = {
|
|
184
|
+
Successful: [{ Id: '0' }, { Id: '1' }],
|
|
185
|
+
Failed: [],
|
|
186
|
+
};
|
|
187
|
+
sqsMock.on(DeleteMessageBatchCommand).resolves(batchResp);
|
|
188
|
+
const queueAdapter = new SqsQueueAdapter(Logger, { skipQueueExistsCheck: true });
|
|
189
|
+
const messages: Message[] = [
|
|
190
|
+
{
|
|
191
|
+
MessageId: 'msg-1',
|
|
192
|
+
ReceiptHandle: 'receipt-1',
|
|
193
|
+
Body: JSON.stringify({ event: 'loading' }),
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
MessageId: 'msg-2',
|
|
197
|
+
ReceiptHandle: 'receipt-2',
|
|
198
|
+
Body: JSON.stringify({ event: 'playing' }),
|
|
199
|
+
},
|
|
200
|
+
];
|
|
201
|
+
const result = await queueAdapter.removeFromQueueBatch(messages);
|
|
202
|
+
expect(result).toEqual({ successful: batchResp.Successful, failed: [] });
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it('should handle empty messages array in batch remove', async () => {
|
|
206
|
+
const queueAdapter = new SqsQueueAdapter(Logger, { skipQueueExistsCheck: true });
|
|
207
|
+
const result = await queueAdapter.removeFromQueueBatch([]);
|
|
208
|
+
expect(result).toEqual({ successful: [], failed: [] });
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it('should not batch remove from queue if sqs queue env is not set', async () => {
|
|
212
|
+
process.env.SQS_QUEUE_URL = undefined;
|
|
213
|
+
const queueAdapter = new SqsQueueAdapter(Logger);
|
|
214
|
+
const messages: Message[] = [
|
|
215
|
+
{
|
|
216
|
+
MessageId: 'msg-1',
|
|
217
|
+
ReceiptHandle: 'receipt-1',
|
|
218
|
+
Body: JSON.stringify({ event: 'loading' }),
|
|
219
|
+
},
|
|
220
|
+
];
|
|
221
|
+
const result = await queueAdapter.removeFromQueueBatch(messages);
|
|
222
|
+
expect(result).toEqual({ message: 'SQS_QUEUE_URL is undefined' });
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it('should handle batch delete with more than 10 messages', async () => {
|
|
226
|
+
const batchResp = {
|
|
227
|
+
Successful: Array.from({ length: 10 }, (_, i) => ({ Id: `${i}` })),
|
|
228
|
+
Failed: [],
|
|
229
|
+
};
|
|
230
|
+
sqsMock.on(DeleteMessageBatchCommand).resolves(batchResp);
|
|
231
|
+
const queueAdapter = new SqsQueueAdapter(Logger, { skipQueueExistsCheck: true });
|
|
232
|
+
const messages: Message[] = Array.from({ length: 15 }, (_, i) => ({
|
|
233
|
+
MessageId: `msg-${i}`,
|
|
234
|
+
ReceiptHandle: `receipt-${i}`,
|
|
235
|
+
Body: JSON.stringify({ event: 'loading' }),
|
|
236
|
+
}));
|
|
237
|
+
const result: any = await queueAdapter.removeFromQueueBatch(messages);
|
|
238
|
+
// Should make 2 batch calls (10 + 5 messages)
|
|
239
|
+
expect(result.successful.length).toBe(20); // 10 from first batch + 10 from second mock response
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
it('should handle batch delete errors', async () => {
|
|
243
|
+
const errMsg: AwsError = {
|
|
244
|
+
Type: 'Sender',
|
|
245
|
+
Code: 'AWS.SimpleQueueService.NonExistentQueue',
|
|
246
|
+
name: 'AWS.SimpleQueueService.NonExistentQueue',
|
|
247
|
+
$fault: 'client',
|
|
248
|
+
$metadata: {
|
|
249
|
+
httpStatusCode: 400,
|
|
250
|
+
requestId: 'df840ab9-e68b-5c0e-b4a0-5094f2dfaee8',
|
|
251
|
+
attempts: 1,
|
|
252
|
+
totalRetryDelay: 0,
|
|
253
|
+
},
|
|
254
|
+
};
|
|
255
|
+
sqsMock.on(DeleteMessageBatchCommand).rejects(errMsg);
|
|
256
|
+
const queueAdapter = new SqsQueueAdapter(Logger, { skipQueueExistsCheck: true });
|
|
257
|
+
const messages: Message[] = [
|
|
258
|
+
{
|
|
259
|
+
MessageId: 'msg-1',
|
|
260
|
+
ReceiptHandle: 'receipt-1',
|
|
261
|
+
Body: JSON.stringify({ event: 'loading' }),
|
|
262
|
+
},
|
|
263
|
+
];
|
|
264
|
+
const result: any = await queueAdapter.removeFromQueueBatch(messages);
|
|
265
|
+
expect(result.failed.length).toBe(1);
|
|
266
|
+
expect(result.failed[0].Code).toBe('BatchError');
|
|
267
|
+
});
|
|
163
268
|
});
|
package/types/queue.ts
CHANGED
|
@@ -13,5 +13,6 @@ export abstract class AbstractQueueAdapter {
|
|
|
13
13
|
abstract pushToQueue(body: Object): Promise<Object>;
|
|
14
14
|
abstract pullFromQueue(): Promise<Object>;
|
|
15
15
|
abstract removeFromQueue(body: Object): Promise<Object>;
|
|
16
|
+
abstract removeFromQueueBatch(messages: Object[]): Promise<Object>;
|
|
16
17
|
abstract getEventJSONsFromMessages(body: any[]): Object[];
|
|
17
18
|
}
|