@loipv/nestjs-kafka 0.0.2 → 0.0.4
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/README.md +44 -0
- package/dist/interfaces/consumer-options.interface.d.ts +9 -0
- package/dist/services/consumer-registry.service.d.ts +6 -4
- package/dist/services/consumer-registry.service.js +177 -81
- package/dist/services/consumer-registry.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -253,6 +253,40 @@ async handleBinary(message: KafkaMessage) {
|
|
|
253
253
|
}
|
|
254
254
|
```
|
|
255
255
|
|
|
256
|
+
### Retry & Restart on Failure
|
|
257
|
+
|
|
258
|
+
Control consumer restart behavior when errors occur:
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
// Disable restart on failure
|
|
262
|
+
@Consumer('critical-topic', {
|
|
263
|
+
retry: {
|
|
264
|
+
restartOnFailure: false,
|
|
265
|
+
},
|
|
266
|
+
})
|
|
267
|
+
async handleCritical(message: KafkaMessagePayload) {
|
|
268
|
+
// Consumer will NOT restart if this throws
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Custom restart logic
|
|
272
|
+
@Consumer('orders', {
|
|
273
|
+
retry: {
|
|
274
|
+
retries: 10,
|
|
275
|
+
maxRetryTime: 60000,
|
|
276
|
+
restartOnFailure: async (error) => {
|
|
277
|
+
// Don't restart on authentication errors
|
|
278
|
+
if (error.message.includes('authentication')) {
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
return true; // Restart for other errors
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
})
|
|
285
|
+
async handleOrders(message: KafkaMessagePayload) {
|
|
286
|
+
// Process order
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
256
290
|
### All Consumer Options
|
|
257
291
|
|
|
258
292
|
```typescript
|
|
@@ -295,6 +329,16 @@ interface ConsumerOptions {
|
|
|
295
329
|
autoCommit?: boolean; // Default: true
|
|
296
330
|
autoCommitInterval?: number;
|
|
297
331
|
fromBeginning?: boolean; // Default: false
|
|
332
|
+
|
|
333
|
+
// Retry & restart on failure
|
|
334
|
+
retry?: {
|
|
335
|
+
retries?: number; // Default: 5
|
|
336
|
+
maxRetryTime?: number; // Default: 30000
|
|
337
|
+
initialRetryTime?: number; // Default: 300
|
|
338
|
+
factor?: number; // Default: 0.2
|
|
339
|
+
multiplier?: number; // Default: 2
|
|
340
|
+
restartOnFailure?: boolean | ((error: Error) => Promise<boolean>);
|
|
341
|
+
};
|
|
298
342
|
}
|
|
299
343
|
```
|
|
300
344
|
|
|
@@ -7,6 +7,14 @@ export interface DlqOptions {
|
|
|
7
7
|
includeOriginalHeaders?: boolean;
|
|
8
8
|
includeErrorInfo?: boolean;
|
|
9
9
|
}
|
|
10
|
+
export interface ConsumerRetryOptions {
|
|
11
|
+
retries?: number;
|
|
12
|
+
maxRetryTime?: number;
|
|
13
|
+
initialRetryTime?: number;
|
|
14
|
+
factor?: number;
|
|
15
|
+
multiplier?: number;
|
|
16
|
+
restartOnFailure?: boolean | ((error: Error) => Promise<boolean>);
|
|
17
|
+
}
|
|
10
18
|
export interface ConsumerOptions {
|
|
11
19
|
topic?: string;
|
|
12
20
|
disabled?: boolean;
|
|
@@ -30,6 +38,7 @@ export interface ConsumerOptions {
|
|
|
30
38
|
autoCommitInterval?: number;
|
|
31
39
|
autoCommitThreshold?: number;
|
|
32
40
|
fromBeginning?: boolean;
|
|
41
|
+
retry?: ConsumerRetryOptions;
|
|
33
42
|
}
|
|
34
43
|
export interface ConsumerMetadata {
|
|
35
44
|
topic: string;
|
|
@@ -12,15 +12,17 @@ export declare class ConsumerRegistryService implements OnApplicationShutdown {
|
|
|
12
12
|
private readonly pressureManager;
|
|
13
13
|
private readonly dlqService;
|
|
14
14
|
private readonly logger;
|
|
15
|
-
private
|
|
15
|
+
private consumerGroups;
|
|
16
16
|
private isShuttingDown;
|
|
17
17
|
constructor(kafkaCore: KafkaCoreService, batchProcessor: BatchProcessorService, idempotencyService: IdempotencyService, pressureManager: PressureManagerService, dlqService: DlqService);
|
|
18
18
|
registerConsumers(consumers: ConsumerMetadata[]): void;
|
|
19
19
|
private registerConsumer;
|
|
20
|
+
private buildRestartOnFailure;
|
|
20
21
|
startAll(): Promise<void>;
|
|
21
|
-
private
|
|
22
|
-
private
|
|
23
|
-
private
|
|
22
|
+
private startConsumerGroup;
|
|
23
|
+
private startMessageGroupConsumer;
|
|
24
|
+
private startBatchGroupConsumer;
|
|
25
|
+
private processBatchMessages;
|
|
24
26
|
private handleError;
|
|
25
27
|
gracefulShutdown(): Promise<void>;
|
|
26
28
|
onApplicationShutdown(): Promise<void>;
|
|
@@ -25,7 +25,7 @@ let ConsumerRegistryService = ConsumerRegistryService_1 = class ConsumerRegistry
|
|
|
25
25
|
pressureManager;
|
|
26
26
|
dlqService;
|
|
27
27
|
logger = new common_1.Logger(ConsumerRegistryService_1.name);
|
|
28
|
-
|
|
28
|
+
consumerGroups = new Map();
|
|
29
29
|
isShuttingDown = false;
|
|
30
30
|
constructor(kafkaCore, batchProcessor, idempotencyService, pressureManager, dlqService) {
|
|
31
31
|
this.kafkaCore = kafkaCore;
|
|
@@ -40,80 +40,123 @@ let ConsumerRegistryService = ConsumerRegistryService_1 = class ConsumerRegistry
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
registerConsumer(metadata) {
|
|
43
|
-
const { topic, options } = metadata;
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
43
|
+
const { topic, options, target, methodName } = metadata;
|
|
44
|
+
const groupId = options.groupId || `${topic}-group`;
|
|
45
|
+
let group = this.consumerGroups.get(groupId);
|
|
46
|
+
if (!group) {
|
|
47
|
+
const consumer = this.kafkaCore.getKafka().consumer({
|
|
48
|
+
groupId,
|
|
49
|
+
sessionTimeout: options.sessionTimeout,
|
|
50
|
+
heartbeatInterval: options.heartbeatInterval,
|
|
51
|
+
rebalanceTimeout: options.rebalanceTimeout,
|
|
52
|
+
maxBytesPerPartition: 1048576,
|
|
53
|
+
retry: options.retry
|
|
54
|
+
? {
|
|
55
|
+
retries: options.retry.retries,
|
|
56
|
+
maxRetryTime: options.retry.maxRetryTime,
|
|
57
|
+
initialRetryTime: options.retry.initialRetryTime,
|
|
58
|
+
factor: options.retry.factor,
|
|
59
|
+
multiplier: options.retry.multiplier,
|
|
60
|
+
}
|
|
61
|
+
: undefined,
|
|
62
|
+
});
|
|
63
|
+
group = {
|
|
64
|
+
groupId,
|
|
65
|
+
consumer,
|
|
66
|
+
topics: new Map(),
|
|
67
|
+
options,
|
|
68
|
+
isRunning: false,
|
|
69
|
+
hasBatchConsumer: false,
|
|
70
|
+
};
|
|
71
|
+
this.consumerGroups.set(groupId, group);
|
|
72
|
+
this.pressureManager.register(groupId, consumer, {
|
|
73
|
+
backPressureThreshold: options.backPressureThreshold || 80,
|
|
74
|
+
resumeThreshold: 60,
|
|
75
|
+
maxQueueSize: options.maxQueueSize || 1000,
|
|
76
|
+
checkIntervalMs: 1000,
|
|
77
|
+
});
|
|
78
|
+
this.logger.log(`Created consumer group: ${groupId}`);
|
|
79
|
+
}
|
|
80
|
+
if (options.batch) {
|
|
81
|
+
group.hasBatchConsumer = true;
|
|
82
|
+
}
|
|
83
|
+
const handler = target[methodName].bind(target);
|
|
84
|
+
group.topics.set(topic, { metadata, handler });
|
|
85
|
+
this.logger.log(`Registered topic "${topic}" in group "${groupId}"`);
|
|
86
|
+
}
|
|
87
|
+
buildRestartOnFailure(retry) {
|
|
88
|
+
if (!retry?.restartOnFailure) {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
if (typeof retry.restartOnFailure === 'function') {
|
|
92
|
+
return retry.restartOnFailure;
|
|
93
|
+
}
|
|
94
|
+
return () => Promise.resolve(retry.restartOnFailure);
|
|
64
95
|
}
|
|
65
96
|
async startAll() {
|
|
66
|
-
const startPromises = Array.from(this.
|
|
97
|
+
const startPromises = Array.from(this.consumerGroups.values()).map((group) => this.startConsumerGroup(group));
|
|
67
98
|
await Promise.all(startPromises);
|
|
68
99
|
}
|
|
69
|
-
async
|
|
70
|
-
const {
|
|
71
|
-
const { topic, options } = metadata;
|
|
100
|
+
async startConsumerGroup(group) {
|
|
101
|
+
const { groupId, consumer, topics } = group;
|
|
72
102
|
try {
|
|
73
103
|
await consumer.connect();
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
104
|
+
const topicList = Array.from(topics.keys());
|
|
105
|
+
for (const topic of topicList) {
|
|
106
|
+
const topicHandler = topics.get(topic);
|
|
107
|
+
await consumer.subscribe({
|
|
108
|
+
topic,
|
|
109
|
+
fromBeginning: topicHandler.metadata.options.fromBeginning,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
this.logger.log(`Consumer group "${groupId}" subscribed to topics: ${topicList.join(', ')}`);
|
|
113
|
+
if (group.hasBatchConsumer) {
|
|
114
|
+
await this.startBatchGroupConsumer(group);
|
|
80
115
|
}
|
|
81
116
|
else {
|
|
82
|
-
await this.
|
|
117
|
+
await this.startMessageGroupConsumer(group);
|
|
83
118
|
}
|
|
84
|
-
|
|
85
|
-
this.logger.log(`Started consumer
|
|
119
|
+
group.isRunning = true;
|
|
120
|
+
this.logger.log(`Started consumer group: ${groupId}`);
|
|
86
121
|
}
|
|
87
122
|
catch (error) {
|
|
88
|
-
this.logger.error(`Failed to start consumer
|
|
123
|
+
this.logger.error(`Failed to start consumer group: ${groupId}`, error);
|
|
89
124
|
throw error;
|
|
90
125
|
}
|
|
91
126
|
}
|
|
92
|
-
async
|
|
93
|
-
const {
|
|
94
|
-
const
|
|
95
|
-
const handler = target[methodName].bind(target);
|
|
127
|
+
async startMessageGroupConsumer(group) {
|
|
128
|
+
const { consumer, topics, options } = group;
|
|
129
|
+
const restartOnFailure = this.buildRestartOnFailure(options.retry);
|
|
96
130
|
await consumer.run({
|
|
97
131
|
autoCommit: options.autoCommit !== false,
|
|
98
132
|
autoCommitInterval: options.autoCommitInterval,
|
|
99
133
|
autoCommitThreshold: options.autoCommitThreshold,
|
|
134
|
+
partitionsConsumedConcurrently: options.partitionsConsumedConcurrently,
|
|
135
|
+
...(restartOnFailure && { restartOnFailure }),
|
|
100
136
|
eachMessage: async (payload) => {
|
|
101
137
|
if (this.isShuttingDown)
|
|
102
138
|
return;
|
|
103
|
-
const { message, partition } = payload;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
139
|
+
const { topic, message, partition } = payload;
|
|
140
|
+
const topicHandler = topics.get(topic);
|
|
141
|
+
if (!topicHandler) {
|
|
142
|
+
this.logger.warn(`No handler found for topic: ${topic}`);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const { metadata, handler } = topicHandler;
|
|
146
|
+
const topicOptions = metadata.options;
|
|
147
|
+
if (topicOptions.idempotencyKey) {
|
|
148
|
+
if (this.idempotencyService.isProcessed(message, topicOptions.idempotencyKey)) {
|
|
149
|
+
this.logger.debug(`Skipping duplicate message from ${topic}`);
|
|
107
150
|
return;
|
|
108
151
|
}
|
|
109
152
|
}
|
|
110
153
|
try {
|
|
111
|
-
const processedMessage =
|
|
154
|
+
const processedMessage = topicOptions.deserialize !== false
|
|
112
155
|
? (0, interfaces_1.deserializeMessage)(message, topic, partition)
|
|
113
156
|
: message;
|
|
114
157
|
await handler(processedMessage);
|
|
115
|
-
if (
|
|
116
|
-
this.idempotencyService.markProcessed(message,
|
|
158
|
+
if (topicOptions.idempotencyKey) {
|
|
159
|
+
this.idempotencyService.markProcessed(message, topicOptions.idempotencyKey);
|
|
117
160
|
}
|
|
118
161
|
this.dlqService.clearRetryState(message, topic, partition);
|
|
119
162
|
}
|
|
@@ -123,38 +166,91 @@ let ConsumerRegistryService = ConsumerRegistryService_1 = class ConsumerRegistry
|
|
|
123
166
|
},
|
|
124
167
|
});
|
|
125
168
|
}
|
|
126
|
-
async
|
|
127
|
-
const {
|
|
128
|
-
const
|
|
129
|
-
const handler = target[methodName].bind(target);
|
|
130
|
-
const eachBatchHandler = this.batchProcessor.createEachBatchHandler(options, async (messages, topic, partition) => {
|
|
131
|
-
if (this.isShuttingDown)
|
|
132
|
-
return;
|
|
133
|
-
let processableMessages = messages;
|
|
134
|
-
if (options.idempotencyKey) {
|
|
135
|
-
processableMessages = this.idempotencyService.filterDuplicates(messages, options.idempotencyKey);
|
|
136
|
-
}
|
|
137
|
-
const deserializedMessages = options.deserialize !== false
|
|
138
|
-
? processableMessages.map((msg) => (0, interfaces_1.deserializeMessage)(msg, topic, partition))
|
|
139
|
-
: processableMessages;
|
|
140
|
-
if (options.groupByKey) {
|
|
141
|
-
const grouped = this.batchProcessor.groupMessagesByKey(deserializedMessages);
|
|
142
|
-
await handler(grouped);
|
|
143
|
-
}
|
|
144
|
-
else {
|
|
145
|
-
await handler(deserializedMessages);
|
|
146
|
-
}
|
|
147
|
-
if (options.idempotencyKey) {
|
|
148
|
-
for (const msg of processableMessages) {
|
|
149
|
-
this.idempotencyService.markProcessed(msg, options.idempotencyKey);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
});
|
|
169
|
+
async startBatchGroupConsumer(group) {
|
|
170
|
+
const { consumer, topics, options } = group;
|
|
171
|
+
const restartOnFailure = this.buildRestartOnFailure(options.retry);
|
|
153
172
|
await consumer.run({
|
|
154
173
|
autoCommit: false,
|
|
155
|
-
|
|
174
|
+
partitionsConsumedConcurrently: options.partitionsConsumedConcurrently,
|
|
175
|
+
...(restartOnFailure && { restartOnFailure }),
|
|
176
|
+
eachBatch: async (payload) => {
|
|
177
|
+
if (this.isShuttingDown)
|
|
178
|
+
return;
|
|
179
|
+
const { batch } = payload;
|
|
180
|
+
const { topic, partition, messages } = batch;
|
|
181
|
+
const topicHandler = topics.get(topic);
|
|
182
|
+
if (!topicHandler) {
|
|
183
|
+
this.logger.warn(`No handler found for topic: ${topic}`);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const { metadata, handler } = topicHandler;
|
|
187
|
+
const topicOptions = metadata.options;
|
|
188
|
+
if (topicOptions.batch) {
|
|
189
|
+
const accumulator = this.batchProcessor.createBatchAccumulator(topicOptions);
|
|
190
|
+
accumulator.onFlush(async (batchMessages) => {
|
|
191
|
+
await this.processBatchMessages(batchMessages, topic, partition, topicOptions, handler);
|
|
192
|
+
});
|
|
193
|
+
for (const message of messages) {
|
|
194
|
+
if (!payload.isRunning() || payload.isStale())
|
|
195
|
+
break;
|
|
196
|
+
await accumulator.add(message);
|
|
197
|
+
payload.resolveOffset(message.offset);
|
|
198
|
+
await payload.heartbeat();
|
|
199
|
+
}
|
|
200
|
+
await accumulator.flush();
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
for (const message of messages) {
|
|
204
|
+
if (!payload.isRunning() || payload.isStale())
|
|
205
|
+
break;
|
|
206
|
+
if (topicOptions.idempotencyKey) {
|
|
207
|
+
if (this.idempotencyService.isProcessed(message, topicOptions.idempotencyKey)) {
|
|
208
|
+
payload.resolveOffset(message.offset);
|
|
209
|
+
await payload.heartbeat();
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
try {
|
|
214
|
+
const processedMessage = topicOptions.deserialize !== false
|
|
215
|
+
? (0, interfaces_1.deserializeMessage)(message, topic, partition)
|
|
216
|
+
: message;
|
|
217
|
+
await handler(processedMessage);
|
|
218
|
+
if (topicOptions.idempotencyKey) {
|
|
219
|
+
this.idempotencyService.markProcessed(message, topicOptions.idempotencyKey);
|
|
220
|
+
}
|
|
221
|
+
this.dlqService.clearRetryState(message, topic, partition);
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
await this.handleError(message, error, metadata, partition);
|
|
225
|
+
}
|
|
226
|
+
payload.resolveOffset(message.offset);
|
|
227
|
+
await payload.heartbeat();
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
},
|
|
156
231
|
});
|
|
157
232
|
}
|
|
233
|
+
async processBatchMessages(messages, topic, partition, options, handler) {
|
|
234
|
+
let processableMessages = messages;
|
|
235
|
+
if (options.idempotencyKey) {
|
|
236
|
+
processableMessages = this.idempotencyService.filterDuplicates(messages, options.idempotencyKey);
|
|
237
|
+
}
|
|
238
|
+
const deserializedMessages = options.deserialize !== false
|
|
239
|
+
? processableMessages.map((msg) => (0, interfaces_1.deserializeMessage)(msg, topic, partition))
|
|
240
|
+
: processableMessages;
|
|
241
|
+
if (options.groupByKey) {
|
|
242
|
+
const grouped = this.batchProcessor.groupMessagesByKey(deserializedMessages);
|
|
243
|
+
await handler(grouped);
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
await handler(deserializedMessages);
|
|
247
|
+
}
|
|
248
|
+
if (options.idempotencyKey) {
|
|
249
|
+
for (const msg of processableMessages) {
|
|
250
|
+
this.idempotencyService.markProcessed(msg, options.idempotencyKey);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
158
254
|
async handleError(message, error, metadata, partition) {
|
|
159
255
|
const { topic, options } = metadata;
|
|
160
256
|
this.logger.error(`Error processing message from ${topic}`, error);
|
|
@@ -171,20 +267,20 @@ let ConsumerRegistryService = ConsumerRegistryService_1 = class ConsumerRegistry
|
|
|
171
267
|
async gracefulShutdown() {
|
|
172
268
|
this.isShuttingDown = true;
|
|
173
269
|
this.logger.log('Starting graceful shutdown of consumers...');
|
|
174
|
-
const shutdownPromises = Array.from(this.
|
|
270
|
+
const shutdownPromises = Array.from(this.consumerGroups.values()).map(async (group) => {
|
|
175
271
|
try {
|
|
176
|
-
if (
|
|
177
|
-
await
|
|
178
|
-
await
|
|
272
|
+
if (group.isRunning) {
|
|
273
|
+
await group.consumer.stop();
|
|
274
|
+
await group.consumer.disconnect();
|
|
179
275
|
}
|
|
180
276
|
}
|
|
181
277
|
catch (error) {
|
|
182
|
-
this.logger.error(
|
|
278
|
+
this.logger.error(`Error during consumer group shutdown: ${group.groupId}`, error);
|
|
183
279
|
}
|
|
184
280
|
});
|
|
185
281
|
await Promise.all(shutdownPromises);
|
|
186
282
|
this.idempotencyService.stopCleanup();
|
|
187
|
-
this.logger.log('All
|
|
283
|
+
this.logger.log('All consumer groups shut down gracefully');
|
|
188
284
|
}
|
|
189
285
|
async onApplicationShutdown() {
|
|
190
286
|
await this.gracefulShutdown();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consumer-registry.service.js","sourceRoot":"","sources":["../../lib/services/consumer-registry.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"consumer-registry.service.js","sourceRoot":"","sources":["../../lib/services/consumer-registry.service.ts"],"names":[],"mappings":"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"}
|