@restorecommerce/kafka-client 1.2.13 → 1.2.15

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.
@@ -1,30 +1,33 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __rest = (this && this.__rest) || function (s, e) {
12
- var t = {};
13
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
- t[p] = s[p];
15
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
- t[p[i]] = s[p[i]];
19
- }
20
- return t;
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
21
24
  };
22
25
  Object.defineProperty(exports, "__esModule", { value: true });
23
26
  exports.Name = exports.Kafka = exports.Topic = void 0;
24
- const retry = require("retry");
25
- const _ = require("lodash");
27
+ const retry = __importStar(require("retry"));
28
+ const _ = __importStar(require("lodash"));
26
29
  const events_1 = require("events");
27
- const async = require("async");
30
+ const async = __importStar(require("async"));
28
31
  const kafkajs_1 = require("kafkajs");
29
32
  const protos_1 = require("../../../protos");
30
33
  const makeProtoResolver = (protoFilePath, protoRoot) => {
@@ -41,6 +44,20 @@ const makeProtoResolver = (protoFilePath, protoRoot) => {
41
44
  * A Kafka topic.
42
45
  */
43
46
  class Topic {
47
+ name;
48
+ emitter;
49
+ provider;
50
+ subscribed;
51
+ waitQueue;
52
+ currentOffset;
53
+ consumer;
54
+ config;
55
+ // message sync throttling attributes
56
+ asyncQueue;
57
+ drainEvent;
58
+ // default process one message at at time
59
+ asyncLimit = 1;
60
+ manualOffsetCommit;
44
61
  /**
45
62
  * Kafka topic.
46
63
  * When the listener count for all events are zero, the consumer unsubscribes
@@ -53,8 +70,6 @@ class Topic {
53
70
  * @param config
54
71
  */
55
72
  constructor(name, provider, config, manualOffsetCommit = false) {
56
- // default process one message at at time
57
- this.asyncLimit = 1;
58
73
  this.name = name;
59
74
  this.emitter = new events_1.EventEmitter();
60
75
  this.provider = provider;
@@ -64,33 +79,31 @@ class Topic {
64
79
  this.config = config;
65
80
  this.manualOffsetCommit = manualOffsetCommit;
66
81
  }
67
- createIfNotExists() {
68
- return __awaiter(this, void 0, void 0, function* () {
69
- return new Promise((resolve, reject) => {
70
- this.provider.admin.listTopics().then((topics) => {
71
- if (topics.indexOf(this.name) < 0) {
72
- const operation = retry.operation();
73
- operation.attempt(() => __awaiter(this, void 0, void 0, function* () {
74
- this.provider.admin.createTopics({
75
- topics: [{
76
- topic: this.name
77
- }],
78
- }).then(() => {
79
- this.provider.logger.info(`Topic ${this.name} created successfully`);
80
- resolve();
81
- }).catch(err => {
82
- this.provider.logger.error(`Cannot create topic ${this.name}:`, { code: err.code, message: err.message, stack: err.stack });
83
- operation.retry(err);
84
- const attemptNo = operation.attempts();
85
- this.provider.logger.info(`Retry creating the Topic, attempt no: ${attemptNo}`);
86
- });
87
- }));
88
- }
89
- else {
90
- this.provider.logger.warn(`Topic ${this.name} already exists`);
91
- resolve();
92
- }
93
- });
82
+ async createIfNotExists() {
83
+ return new Promise((resolve, reject) => {
84
+ this.provider.admin.listTopics().then((topics) => {
85
+ if (topics.indexOf(this.name) < 0) {
86
+ const operation = retry.operation();
87
+ operation.attempt(async () => {
88
+ this.provider.admin.createTopics({
89
+ topics: [{
90
+ topic: this.name
91
+ }],
92
+ }).then(() => {
93
+ this.provider.logger.info(`Topic ${this.name} created successfully`);
94
+ resolve();
95
+ }).catch(err => {
96
+ this.provider.logger.error(`Cannot create topic ${this.name}:`, { code: err.code, message: err.message, stack: err.stack });
97
+ operation.retry(err);
98
+ const attemptNo = operation.attempts();
99
+ this.provider.logger.info(`Retry creating the Topic, attempt no: ${attemptNo}`);
100
+ });
101
+ });
102
+ }
103
+ else {
104
+ this.provider.logger.warn(`Topic ${this.name} already exists`);
105
+ resolve();
106
+ }
94
107
  });
95
108
  });
96
109
  }
@@ -128,14 +141,12 @@ class Topic {
128
141
  * @param {string} eventName Name of the event
129
142
  * @param {function|generator} listener Event listener
130
143
  */
131
- removeListener(eventName, listener) {
132
- return __awaiter(this, void 0, void 0, function* () {
133
- this.provider.logger.verbose(`Removing listener from event ${eventName}`);
134
- this.emitter.removeListener(eventName, listener);
135
- if (this.listenerCount(eventName) === 0) {
136
- yield this.$unsubscribe(eventName);
137
- }
138
- });
144
+ async removeListener(eventName, listener) {
145
+ this.provider.logger.verbose(`Removing listener from event ${eventName}`);
146
+ this.emitter.removeListener(eventName, listener);
147
+ if (this.listenerCount(eventName) === 0) {
148
+ await this.$unsubscribe(eventName);
149
+ }
139
150
  }
140
151
  /**
141
152
  * Remove all listeners from given event.
@@ -143,14 +154,12 @@ class Topic {
143
154
  *
144
155
  * @param {string} eventName Name of the event
145
156
  */
146
- removeAllListeners(eventName) {
147
- return __awaiter(this, void 0, void 0, function* () {
148
- this.provider.logger.verbose(`Removing all listeners from event ${eventName}`);
149
- this.emitter.removeAllListeners(eventName);
150
- if (this.listenerCount(eventName) === 0) {
151
- yield this.$unsubscribe(eventName);
152
- }
153
- });
157
+ async removeAllListeners(eventName) {
158
+ this.provider.logger.verbose(`Removing all listeners from event ${eventName}`);
159
+ this.emitter.removeAllListeners(eventName);
160
+ if (this.listenerCount(eventName) === 0) {
161
+ await this.$unsubscribe(eventName);
162
+ }
154
163
  }
155
164
  /**
156
165
  * Return the offset number of this topic.
@@ -158,23 +167,21 @@ class Topic {
158
167
  * @param {number} time Use -1 for latest and 0 for earliest.
159
168
  * @return {number} offset number
160
169
  */
161
- $offset() {
162
- return __awaiter(this, arguments, void 0, function* (time = -1) {
163
- return new Promise((resolve, reject) => {
164
- if (time < 0) {
165
- return this.provider.admin.fetchTopicOffsets(this.name).then(data => {
166
- resolve(parseInt(data[0].offset, 10));
167
- }).catch(err => {
168
- this.provider.logger.error('Error occurred retrieving topic offset:', { code: err.code, message: err.message, stack: err.stack });
169
- reject(err);
170
- });
171
- }
172
- return this.provider.admin.fetchTopicOffsetsByTimestamp(this.name, time).then(data => {
170
+ async $offset(time = -1) {
171
+ return new Promise((resolve, reject) => {
172
+ if (time < 0) {
173
+ return this.provider.admin.fetchTopicOffsets(this.name).then(data => {
173
174
  resolve(parseInt(data[0].offset, 10));
174
175
  }).catch(err => {
175
176
  this.provider.logger.error('Error occurred retrieving topic offset:', { code: err.code, message: err.message, stack: err.stack });
176
177
  reject(err);
177
178
  });
179
+ }
180
+ return this.provider.admin.fetchTopicOffsetsByTimestamp(this.name, time).then(data => {
181
+ resolve(parseInt(data[0].offset, 10));
182
+ }).catch(err => {
183
+ this.provider.logger.error('Error occurred retrieving topic offset:', { code: err.code, message: err.message, stack: err.stack });
184
+ reject(err);
178
185
  });
179
186
  });
180
187
  }
@@ -184,18 +191,16 @@ class Topic {
184
191
  * @return {Promise} Thunk will be resolved when a message is received
185
192
  * with the corresponding offset.
186
193
  */
187
- $wait(offset) {
188
- return __awaiter(this, void 0, void 0, function* () {
189
- return new Promise((() => {
190
- return (cb) => {
191
- if (this.currentOffset >= offset) {
192
- cb(null);
193
- return;
194
- }
195
- this.waitQueue.push({ offset, cb });
196
- };
197
- })());
198
- });
194
+ async $wait(offset) {
195
+ return new Promise((() => {
196
+ return (cb) => {
197
+ if (this.currentOffset >= offset) {
198
+ cb(null);
199
+ return;
200
+ }
201
+ this.waitQueue.push({ offset, cb });
202
+ };
203
+ })());
199
204
  }
200
205
  /**
201
206
  * Reset consumer, unsubscribes all the events on the topic and then
@@ -204,28 +209,26 @@ class Topic {
204
209
  * @param {string[]} eventNames list of event names
205
210
  * @param {number} offset The offset at which to restart from.
206
211
  */
207
- $resetConsumer(eventNames, offset) {
208
- return __awaiter(this, void 0, void 0, function* () {
209
- this.provider.logger.info('Event Names for consumer reset', eventNames);
210
- if (eventNames && eventNames.length > 0) {
211
- // since the consumer is set to undefined only when there is no more subscription
212
- // need to unsubcribe all eventNames and then resubcribe at once
213
- const eventNamesList = _.clone(eventNames);
214
- // unsubscribe all events on consumer
215
- for (let eventName of eventNamesList) {
216
- yield this.$unsubscribe(eventName);
217
- this.provider.logger.info(`Unsubscribed event ${eventName}`);
218
- }
219
- // subscribe all events on consumer
220
- for (let eventName of eventNamesList) {
221
- yield this.$subscribe(eventName, offset);
222
- this.provider.logger.info(`Subscribed event ${eventName}`);
223
- }
212
+ async $resetConsumer(eventNames, offset) {
213
+ this.provider.logger.info('Event Names for consumer reset', eventNames);
214
+ if (eventNames && eventNames.length > 0) {
215
+ // since the consumer is set to undefined only when there is no more subscription
216
+ // need to unsubcribe all eventNames and then resubcribe at once
217
+ const eventNamesList = _.clone(eventNames);
218
+ // unsubscribe all events on consumer
219
+ for (const eventName of eventNamesList) {
220
+ await this.$unsubscribe(eventName);
221
+ this.provider.logger.info(`Unsubscribed event ${eventName}`);
224
222
  }
225
- else {
226
- this.provider.logger.warn('Event names empty for consumer reset');
223
+ // subscribe all events on consumer
224
+ for (const eventName of eventNamesList) {
225
+ await this.$subscribe(eventName, offset);
226
+ this.provider.logger.info(`Subscribed event ${eventName}`);
227
227
  }
228
- });
228
+ }
229
+ else {
230
+ this.provider.logger.warn('Event names empty for consumer reset');
231
+ }
229
232
  }
230
233
  /**
231
234
  * Force a committed offset reset.
@@ -233,34 +236,30 @@ class Topic {
233
236
  * @param {string} eventName
234
237
  * @param {number} offset The offset at which to restart from.
235
238
  */
236
- $reset(eventName, offset) {
237
- return __awaiter(this, void 0, void 0, function* () {
238
- if (this.subscribed.indexOf(eventName) > -1) {
239
- yield this.$unsubscribe(eventName);
240
- }
241
- yield this.$subscribe(eventName, offset);
242
- });
239
+ async $reset(eventName, offset) {
240
+ if (this.subscribed.indexOf(eventName) > -1) {
241
+ await this.$unsubscribe(eventName);
242
+ }
243
+ await this.$subscribe(eventName, offset);
243
244
  }
244
245
  /**
245
246
  * Unsubscribe from Kafka topic. Does not remove any listeners.
246
247
  */
247
- $unsubscribe(eventName) {
248
- return __awaiter(this, void 0, void 0, function* () {
249
- if (!_.includes(this.subscribed, eventName)) {
250
- return;
251
- }
252
- const index = this.subscribed.indexOf(eventName);
253
- this.subscribed.splice(index, 1);
254
- if (this.subscribed.length == 0) {
255
- this.provider.logger.info(`Closing consumer from topic ${this.name}`);
256
- yield this.consumer.stop().then(() => this.consumer.disconnect()).then(() => {
257
- this.provider.logger.info(`Consumer disconnected from topic ${this.name}`);
258
- this.consumer = undefined;
259
- }).catch((err) => {
260
- this.provider.logger.error(`Error occurred unsubscribing ${eventName} on topic ${this.name}`, { code: err.code, message: err.message, stack: err.stack });
261
- });
262
- }
263
- });
248
+ async $unsubscribe(eventName) {
249
+ if (!_.includes(this.subscribed, eventName)) {
250
+ return;
251
+ }
252
+ const index = this.subscribed.indexOf(eventName);
253
+ this.subscribed.splice(index, 1);
254
+ if (this.subscribed.length == 0) {
255
+ this.provider.logger.info(`Closing consumer from topic ${this.name}`);
256
+ await this.consumer.stop().then(() => this.consumer.disconnect()).then(() => {
257
+ this.provider.logger.info(`Consumer disconnected from topic ${this.name}`);
258
+ this.consumer = undefined;
259
+ }).catch((err) => {
260
+ this.provider.logger.error(`Error occurred unsubscribing ${eventName} on topic ${this.name}`, { code: err.code, message: err.message, stack: err.stack });
261
+ });
262
+ }
264
263
  }
265
264
  /**
266
265
  * Filters subscribed messages among all received Kafka messages and then
@@ -305,49 +304,47 @@ class Topic {
305
304
  * @param offsetValue
306
305
  * @param queue
307
306
  **/
308
- $subscribe(eventName, offsetValue, queue) {
309
- return __awaiter(this, void 0, void 0, function* () {
310
- if (!this.consumer) {
311
- this.consumer = this.provider.client.consumer({
312
- groupId: this.provider.config.groupId + '_' + this.name
313
- });
314
- yield this.consumer.connect().then(() => {
315
- this.provider.logger.info(`Consumer for topic '${this.name}' connected`);
316
- }).catch(err => {
317
- this.provider.logger.error(`Consumer for topic '${this.name}' connection error`, { code: err.code, message: err.message, stack: err.stack });
318
- });
319
- yield this.consumer.subscribe({
320
- topic: this.name
321
- }).then(() => {
322
- this.provider.logger.info(`Consumer for topic '${this.name}' subscribed`);
323
- }).catch(err => {
324
- this.provider.logger.error(`Consumer for topic '${this.name}' subscriber error`, { code: err.code, message: err.message, stack: err.stack });
325
- });
326
- // On receiving the message on Kafka consumer put the message to async Queue.
327
- if (queue) {
328
- // start drain process
329
- this.drain();
330
- }
331
- yield this.consumer.run({
332
- eachMessage: (payload) => __awaiter(this, void 0, void 0, function* () {
333
- if (queue) {
334
- this.onMessageForQueue(payload);
335
- }
336
- else {
337
- this.makeDataHandler(payload);
338
- }
339
- })
340
- }).catch(err => {
341
- this.provider.logger.error(`Consumer for topic '${this.name}' failed to run`, { code: err.code, message: err.message, stack: err.stack });
342
- });
343
- this.consumer.seek({
344
- topic: this.name,
345
- partition: 0,
346
- offset: offsetValue.toString(10)
347
- });
307
+ async $subscribe(eventName, offsetValue, queue) {
308
+ if (!this.consumer) {
309
+ this.consumer = this.provider.client.consumer({
310
+ groupId: this.provider.config.groupId + '_' + this.name
311
+ });
312
+ await this.consumer.connect().then(() => {
313
+ this.provider.logger.info(`Consumer for topic '${this.name}' connected`);
314
+ }).catch(err => {
315
+ this.provider.logger.error(`Consumer for topic '${this.name}' connection error`, { code: err.code, message: err.message, stack: err.stack });
316
+ });
317
+ await this.consumer.subscribe({
318
+ topic: this.name
319
+ }).then(() => {
320
+ this.provider.logger.info(`Consumer for topic '${this.name}' subscribed`);
321
+ }).catch(err => {
322
+ this.provider.logger.error(`Consumer for topic '${this.name}' subscriber error`, { code: err.code, message: err.message, stack: err.stack });
323
+ });
324
+ // On receiving the message on Kafka consumer put the message to async Queue.
325
+ if (queue) {
326
+ // start drain process
327
+ this.drain();
348
328
  }
349
- this.subscribed.push(eventName);
350
- });
329
+ await this.consumer.run({
330
+ eachMessage: async (payload) => {
331
+ if (queue) {
332
+ this.onMessageForQueue(payload);
333
+ }
334
+ else {
335
+ this.makeDataHandler(payload);
336
+ }
337
+ }
338
+ }).catch(err => {
339
+ this.provider.logger.error(`Consumer for topic '${this.name}' failed to run`, { code: err.code, message: err.message, stack: err.stack });
340
+ });
341
+ this.consumer.seek({
342
+ topic: this.name,
343
+ partition: 0,
344
+ offset: offsetValue.toString(10)
345
+ });
346
+ }
347
+ this.subscribed.push(eventName);
351
348
  }
352
349
  onMessageForQueue(context) {
353
350
  if (_.includes(this.subscribed, context.message.key.toString())) {
@@ -407,37 +404,33 @@ class Topic {
407
404
  });
408
405
  }
409
406
  }
410
- commitCurrentOffsets() {
411
- return __awaiter(this, void 0, void 0, function* () {
412
- return new Promise((resolve, reject) => {
413
- this.consumer.commitOffsets([
414
- {
415
- topic: this.name,
416
- offset: this.currentOffset.toString(10),
417
- partition: 0 // ?
418
- }
419
- ]).then(resolve).catch(err => {
420
- this.provider.logger.error('Error committing offset', { code: err.code, message: err.message, stack: err.stack });
421
- reject(err);
422
- });
407
+ async commitCurrentOffsets() {
408
+ return new Promise((resolve, reject) => {
409
+ this.consumer.commitOffsets([
410
+ {
411
+ topic: this.name,
412
+ offset: this.currentOffset.toString(10),
413
+ partition: 0 // ?
414
+ }
415
+ ]).then(resolve).catch(err => {
416
+ this.provider.logger.error('Error committing offset', { code: err.code, message: err.message, stack: err.stack });
417
+ reject(err);
423
418
  });
424
419
  });
425
420
  }
426
421
  /**
427
422
  * Manually commit the current offset.
428
423
  */
429
- commitOffset() {
430
- return __awaiter(this, void 0, void 0, function* () {
431
- try {
432
- // Commit the current offset
433
- yield this.commitCurrentOffsets();
434
- this.provider.logger.verbose('Offset committed manually');
435
- }
436
- catch (error) {
437
- this.provider.logger.error('Failed to commit offset manually', { code: error.code, message: error.message, stack: error.stack });
438
- throw error;
439
- }
440
- });
424
+ async commitOffset() {
425
+ try {
426
+ // Commit the current offset
427
+ await this.commitCurrentOffsets();
428
+ this.provider.logger.verbose('Offset committed manually');
429
+ }
430
+ catch (error) {
431
+ this.provider.logger.error('Failed to commit offset manually', { code: error.code, message: error.message, stack: error.stack });
432
+ throw error;
433
+ }
441
434
  }
442
435
  /**
443
436
  * Internal function for receiving event messages from Kafka and
@@ -469,19 +462,18 @@ class Topic {
469
462
  * @param {function|generator} listener Listener
470
463
  * @param opts
471
464
  */
472
- on(eventName_1, listener_1) {
473
- return __awaiter(this, arguments, void 0, function* (eventName, listener, opts = {}) {
474
- let { startingOffset, queue, forceOffset } = opts;
475
- if (!(this.subscribed.indexOf(eventName) > -1)) {
476
- if (_.isNil(startingOffset) || (this.config.latestOffset && !forceOffset)) {
477
- // override the startingOffset with the latestOffset from Kafka
478
- // if above config is set
479
- startingOffset = yield this.$offset(-1);
480
- }
481
- yield this.$subscribe(eventName, startingOffset, queue);
465
+ async on(eventName, listener, opts = {}) {
466
+ let { startingOffset } = opts;
467
+ const { queue, forceOffset } = opts;
468
+ if (!(this.subscribed.indexOf(eventName) > -1)) {
469
+ if (_.isNil(startingOffset) || (this.config.latestOffset && !forceOffset)) {
470
+ // override the startingOffset with the latestOffset from Kafka
471
+ // if above config is set
472
+ startingOffset = await this.$offset(-1);
482
473
  }
483
- this.emitter.on(eventName, listener);
484
- });
474
+ await this.$subscribe(eventName, startingOffset, queue);
475
+ }
476
+ this.emitter.on(eventName, listener);
485
477
  }
486
478
  /**
487
479
  * Send event messages.
@@ -489,14 +481,12 @@ class Topic {
489
481
  * @param {string} eventName Event name
490
482
  * @param {Object} message Message
491
483
  */
492
- emit(eventName, message) {
493
- return __awaiter(this, void 0, void 0, function* () {
494
- yield this.provider.$send(this.name, eventName, message);
495
- });
484
+ async emit(eventName, message) {
485
+ await this.provider.$send(this.name, eventName, message);
496
486
  }
497
487
  }
498
488
  exports.Topic = Topic;
499
- const toWinstonLogLevel = level => {
489
+ const toWinstonLogLevel = (level) => {
500
490
  switch (level) {
501
491
  case kafkajs_1.logLevel.ERROR:
502
492
  case kafkajs_1.logLevel.NOTHING:
@@ -513,6 +503,14 @@ const toWinstonLogLevel = level => {
513
503
  * Events provider.
514
504
  */
515
505
  class Kafka {
506
+ config;
507
+ topics;
508
+ logger;
509
+ client;
510
+ producer;
511
+ admin;
512
+ producerConnected;
513
+ adminConnected;
516
514
  /**
517
515
  * Kafka is a provider for Events.
518
516
  *
@@ -530,67 +528,67 @@ class Kafka {
530
528
  * Start connects to kafka with a producer.
531
529
  * Suspends the calling function until the producer is connected.
532
530
  */
533
- start() {
534
- return __awaiter(this, void 0, void 0, function* () {
535
- var _a, _b;
536
- const operation = retry.operation({
537
- forever: true,
538
- maxTimeout: (_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.timeout) !== null && _b !== void 0 ? _b : 60000,
539
- });
540
- return new Promise((resolveRetry) => {
541
- operation.attempt(() => __awaiter(this, void 0, void 0, function* () {
542
- var _a;
543
- try {
544
- this.client = new kafkajs_1.Kafka(Object.assign(Object.assign({ retry: {
545
- initialRetryTime: 1000,
546
- maxRetryTime: 10000,
547
- retries: 100,
548
- } }, this.config.kafka), { logCreator: () => {
549
- return ({ level, log }) => {
550
- const { message } = log, extra = __rest(log, ["message"]);
551
- this.logger.log(toWinstonLogLevel(level), '[kafka-client] ' + message, extra);
552
- };
553
- } }));
554
- this.producer = this.client.producer();
555
- this.admin = this.client.admin();
556
- // waiting for producer to be ready
557
- yield new Promise((resolveProducer, rejectProducer) => {
558
- this.producer.on('producer.connect', () => {
559
- this.producerConnected = true;
560
- this.logger.info('The Producer is ready.');
561
- resolveProducer(true);
562
- });
563
- this.producer.on('producer.disconnect', (err) => {
564
- this.producerConnected = false;
565
- this.logger.warn('The Producer has disconnected:', err);
566
- rejectProducer(err);
567
- });
568
- this.producer.on('producer.network.request_timeout', (err) => {
569
- this.logger.warn('The Producer timed out:', err);
570
- rejectProducer(err);
571
- });
572
- this.producer.connect().catch(err => {
573
- this.logger.warn('Producer connection error:', err);
574
- });
575
- }).then(() => __awaiter(this, void 0, void 0, function* () {
576
- this.admin.on('admin.connect', () => {
577
- this.adminConnected = true;
578
- resolveRetry();
579
- });
580
- this.admin.on('admin.disconnect', () => this.adminConnected = false);
581
- yield this.admin.connect().catch(err => {
582
- this.logger.warn('Admin connection error:', err);
583
- throw err;
584
- });
585
- }));
586
- }
587
- catch (err) {
588
- operation.retry(err);
589
- const attemptNo = operation.attempts();
590
- (_a = this.producer) === null || _a === void 0 ? void 0 : _a.disconnect();
591
- this.logger.info(`Retry initialize the Producer, attempt no: ${attemptNo}`);
592
- }
593
- }));
531
+ async start() {
532
+ const operation = retry.operation({
533
+ forever: true,
534
+ maxTimeout: this.config?.timeout ?? 60000,
535
+ });
536
+ return new Promise((resolveRetry) => {
537
+ operation.attempt(async () => {
538
+ try {
539
+ this.client = new kafkajs_1.Kafka({
540
+ retry: {
541
+ initialRetryTime: 1000,
542
+ maxRetryTime: 10000,
543
+ retries: 100,
544
+ },
545
+ ...this.config.kafka,
546
+ logCreator: () => {
547
+ return ({ level, log }) => {
548
+ const { message, ...extra } = log;
549
+ this.logger.log(toWinstonLogLevel(level), '[kafka-client] ' + message, extra);
550
+ };
551
+ },
552
+ });
553
+ this.producer = this.client.producer();
554
+ this.admin = this.client.admin();
555
+ // waiting for producer to be ready
556
+ await new Promise((resolveProducer, rejectProducer) => {
557
+ this.producer.on('producer.connect', () => {
558
+ this.producerConnected = true;
559
+ this.logger.info('The Producer is ready.');
560
+ resolveProducer(true);
561
+ });
562
+ this.producer.on('producer.disconnect', (err) => {
563
+ this.producerConnected = false;
564
+ this.logger.warn('The Producer has disconnected:', err);
565
+ rejectProducer(err);
566
+ });
567
+ this.producer.on('producer.network.request_timeout', (err) => {
568
+ this.logger.warn('The Producer timed out:', err);
569
+ rejectProducer(err);
570
+ });
571
+ this.producer.connect().catch(err => {
572
+ this.logger.warn('Producer connection error:', err);
573
+ });
574
+ }).then(async () => {
575
+ this.admin.on('admin.connect', () => {
576
+ this.adminConnected = true;
577
+ resolveRetry();
578
+ });
579
+ this.admin.on('admin.disconnect', () => this.adminConnected = false);
580
+ await this.admin.connect().catch(err => {
581
+ this.logger.warn('Admin connection error:', err);
582
+ throw err;
583
+ });
584
+ });
585
+ }
586
+ catch (err) {
587
+ operation.retry(err);
588
+ const attemptNo = operation.attempts();
589
+ this.producer?.disconnect();
590
+ this.logger.info(`Retry initialize the Producer, attempt no: ${attemptNo}`);
591
+ }
594
592
  });
595
593
  });
596
594
  }
@@ -626,53 +624,52 @@ class Kafka {
626
624
  * @param {string} eventName
627
625
  * @param {Object|Object[]} message
628
626
  */
629
- $send(topicName, eventName, message) {
630
- return __awaiter(this, void 0, void 0, function* () {
631
- let messages = message;
632
- const messageObject = this.config[eventName].messageObject;
633
- if (!_.isArray(message)) {
634
- messages = [message];
627
+ async $send(topicName, eventName, message) {
628
+ let messages = message;
629
+ const config = this.config;
630
+ const messageObject = config[eventName].messageObject;
631
+ if (!_.isArray(message)) {
632
+ messages = [message];
633
+ }
634
+ try {
635
+ const values = [];
636
+ for (let i = 0; i < messages.length; i += 1) {
637
+ // get the binary representation of the message using serializeBinary()
638
+ // and build a Buffer from it.
639
+ const msg = messages[i];
640
+ const bufferObj = Kafka.encodeObject(msg, messageObject);
641
+ values.push({
642
+ key: eventName,
643
+ value: Buffer.from(bufferObj),
644
+ partition: 0
645
+ });
635
646
  }
636
- try {
637
- const values = [];
638
- for (let i = 0; i < messages.length; i += 1) {
639
- // get the binary representation of the message using serializeBinary()
640
- // and build a Buffer from it.
641
- const msg = messages[i];
642
- const bufferObj = Kafka.encodeObject(msg, messageObject);
643
- values.push({
644
- key: eventName,
645
- value: Buffer.from(bufferObj),
646
- partition: 0
647
- });
647
+ for (const msg of messages) {
648
+ if (config && config[eventName].omittedFields) {
649
+ const keys = config[eventName].omittedFields;
650
+ this.omitFields(keys, msg, config[eventName].enableLogging);
648
651
  }
649
- for (let msg of messages) {
650
- if (this.config && this.config[eventName].omittedFields) {
651
- const keys = this.config[eventName].omittedFields;
652
- this.omitFields(keys, msg, this.config[eventName].enableLogging);
652
+ }
653
+ this.logger.debug(`Sending event ${eventName} to topic ${topicName}`, { messages });
654
+ return new Promise((resolve, reject) => {
655
+ this.producer.send({
656
+ topic: topicName,
657
+ messages: values
658
+ }).then((data) => {
659
+ for (const msg of messages) {
660
+ this.logger.debug(`Sent event ${eventName} to topic ${topicName}`, msg);
653
661
  }
654
- }
655
- this.logger.debug(`Sending event ${eventName} to topic ${topicName}`, { messages });
656
- return new Promise((resolve, reject) => {
657
- this.producer.send({
658
- topic: topicName,
659
- messages: values
660
- }).then((data) => {
661
- for (let msg of messages) {
662
- this.logger.debug(`Sent event ${eventName} to topic ${topicName}`, msg);
663
- }
664
- resolve(data);
665
- }).catch((err) => {
666
- this.logger.error(`error sending event ${eventName} to topic ${topicName}`, { code: err.code, message: err.message, stack: err.stack });
667
- reject(err);
668
- });
662
+ resolve(data);
663
+ }).catch((err) => {
664
+ this.logger.error(`error sending event ${eventName} to topic ${topicName}`, { code: err.code, message: err.message, stack: err.stack });
665
+ reject(err);
669
666
  });
670
- }
671
- catch (err) {
672
- this.logger.error(`error on sending event ${eventName} to topic ${topicName}`, { code: err.code, message: err.message, stack: err.stack });
673
- throw err;
674
- }
675
- });
667
+ });
668
+ }
669
+ catch (err) {
670
+ this.logger.error(`error on sending event ${eventName} to topic ${topicName}`, { code: err.code, message: err.message, stack: err.stack });
671
+ throw err;
672
+ }
676
673
  }
677
674
  omitFields(keys, msg, enableLogging) {
678
675
  let msgs;
@@ -682,14 +679,14 @@ class Kafka {
682
679
  else {
683
680
  msgs = msg;
684
681
  }
685
- for (let key of keys) {
686
- for (let msg of msgs) {
682
+ for (const key of keys) {
683
+ for (const msg of msgs) {
687
684
  if (typeof key === 'string') {
688
685
  if (enableLogging && msg[key] && msg[key].value) {
689
686
  msg[key] = msg[key].value.toString();
690
687
  }
691
688
  else if (enableLogging && msg[key] && _.isArray(msg[key])) {
692
- for (let eachMsg of msg[key]) {
689
+ for (const eachMsg of msg[key]) {
693
690
  msg[key] = eachMsg.value.toString();
694
691
  }
695
692
  }
@@ -711,53 +708,49 @@ class Kafka {
711
708
  * @param config
712
709
  * @return {Topic} Kafka topic
713
710
  */
714
- topic(topicName, config) {
715
- return __awaiter(this, void 0, void 0, function* () {
716
- if (this.topics[topicName]) {
717
- return this.topics[topicName];
718
- }
719
- this.topics[topicName] = new Topic(topicName, this, config);
720
- yield this.topics[topicName].createIfNotExists();
711
+ async topic(topicName, config) {
712
+ if (this.topics[topicName]) {
721
713
  return this.topics[topicName];
722
- });
714
+ }
715
+ this.topics[topicName] = new Topic(topicName, this, config);
716
+ await this.topics[topicName].createIfNotExists();
717
+ return this.topics[topicName];
723
718
  }
724
719
  /**
725
720
  * stops the connection to kafka.
726
721
  * The calling function is suspended until the producer and
727
722
  * all consumers from topics are disconnected.
728
723
  */
729
- stop() {
730
- return __awaiter(this, void 0, void 0, function* () {
731
- this.logger.warn('Stopping Kafka. Ignore any following connection errors');
732
- const errors = [];
733
- if (this.producerConnected) {
734
- yield this.producer.disconnect().catch(err => {
735
- this.logger.warn('Error occurred stopping Kafka producer:', err);
736
- errors.push(err);
737
- });
738
- }
739
- if (this.adminConnected) {
740
- yield this.admin.disconnect().catch(err => {
741
- this.logger.warn('Error occurred stopping Kafka admin:', err);
742
- errors.push(err);
743
- });
744
- }
745
- const topicNames = _.keys(this.topics);
746
- for (let i = 0; i < topicNames.length; i += 1) {
747
- const topic = this.topics[topicNames[i]];
748
- const eventNames = topic.subscribed;
749
- for (let j = eventNames.length - 1; j >= 0; j -= 1) {
750
- const eventName = eventNames[j];
751
- // This closes both producer and consumer objects
752
- // via unsubscribe()
753
- yield topic.removeAllListeners(eventName);
754
- }
755
- }
756
- if (errors.length > 0) {
757
- this.logger.error('Errors when stopping Kafka client:', errors);
758
- throw errors;
724
+ async stop() {
725
+ this.logger.warn('Stopping Kafka. Ignore any following connection errors');
726
+ const errors = [];
727
+ if (this.producerConnected) {
728
+ await this.producer.disconnect().catch(err => {
729
+ this.logger.warn('Error occurred stopping Kafka producer:', err);
730
+ errors.push(err);
731
+ });
732
+ }
733
+ if (this.adminConnected) {
734
+ await this.admin.disconnect().catch(err => {
735
+ this.logger.warn('Error occurred stopping Kafka admin:', err);
736
+ errors.push(err);
737
+ });
738
+ }
739
+ const topicNames = _.keys(this.topics);
740
+ for (let i = 0; i < topicNames.length; i += 1) {
741
+ const topic = this.topics[topicNames[i]];
742
+ const eventNames = topic.subscribed;
743
+ for (let j = eventNames.length - 1; j >= 0; j -= 1) {
744
+ const eventName = eventNames[j];
745
+ // This closes both producer and consumer objects
746
+ // via unsubscribe()
747
+ await topic.removeAllListeners(eventName);
759
748
  }
760
- });
749
+ }
750
+ if (errors.length > 0) {
751
+ this.logger.error('Errors when stopping Kafka client:', errors);
752
+ throw errors;
753
+ }
761
754
  }
762
755
  }
763
756
  exports.Kafka = Kafka;