@forklaunch/implementation-worker-kafka 0.8.5 → 0.9.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.
@@ -1,3 +1,4 @@
1
+ import { OpenTelemetryCollector, MetricsDefinition } from '@forklaunch/core/http';
1
2
  import { WorkerConsumer } from '@forklaunch/interfaces-worker/interfaces';
2
3
  import { WorkerEventEntity, WorkerProcessFunction, WorkerFailureHandler } from '@forklaunch/interfaces-worker/types';
3
4
  import { KafkaWorkerOptions } from '../domain/types/index.mjs';
@@ -11,7 +12,8 @@ declare class KafkaWorkerConsumer<EventEntity extends WorkerEventEntity, Options
11
12
  protected readonly options: Options;
12
13
  protected readonly processEventsFunction: WorkerProcessFunction<EventEntity>;
13
14
  protected readonly failureHandler: WorkerFailureHandler<EventEntity>;
14
- constructor(queueName: string, options: Options, processEventsFunction: WorkerProcessFunction<EventEntity>, failureHandler: WorkerFailureHandler<EventEntity>);
15
+ protected readonly openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>;
16
+ constructor(queueName: string, options: Options, processEventsFunction: WorkerProcessFunction<EventEntity>, failureHandler: WorkerFailureHandler<EventEntity>, openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>);
15
17
  private setupConsumer;
16
18
  peekEvents(): Promise<EventEntity[]>;
17
19
  start(): Promise<void>;
@@ -1,3 +1,4 @@
1
+ import { OpenTelemetryCollector, MetricsDefinition } from '@forklaunch/core/http';
1
2
  import { WorkerConsumer } from '@forklaunch/interfaces-worker/interfaces';
2
3
  import { WorkerEventEntity, WorkerProcessFunction, WorkerFailureHandler } from '@forklaunch/interfaces-worker/types';
3
4
  import { KafkaWorkerOptions } from '../domain/types/index.js';
@@ -11,7 +12,8 @@ declare class KafkaWorkerConsumer<EventEntity extends WorkerEventEntity, Options
11
12
  protected readonly options: Options;
12
13
  protected readonly processEventsFunction: WorkerProcessFunction<EventEntity>;
13
14
  protected readonly failureHandler: WorkerFailureHandler<EventEntity>;
14
- constructor(queueName: string, options: Options, processEventsFunction: WorkerProcessFunction<EventEntity>, failureHandler: WorkerFailureHandler<EventEntity>);
15
+ protected readonly openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>;
16
+ constructor(queueName: string, options: Options, processEventsFunction: WorkerProcessFunction<EventEntity>, failureHandler: WorkerFailureHandler<EventEntity>, openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>);
15
17
  private setupConsumer;
16
18
  peekEvents(): Promise<EventEntity[]>;
17
19
  start(): Promise<void>;
@@ -35,7 +35,8 @@ var KafkaWorkerConsumer = class {
35
35
  options;
36
36
  processEventsFunction;
37
37
  failureHandler;
38
- constructor(queueName, options, processEventsFunction, failureHandler) {
38
+ openTelemetryCollector;
39
+ constructor(queueName, options, processEventsFunction, failureHandler, openTelemetryCollector) {
39
40
  this.queueName = queueName;
40
41
  this.options = options;
41
42
  this.processEventsFunction = processEventsFunction;
@@ -48,6 +49,7 @@ var KafkaWorkerConsumer = class {
48
49
  this.consumer = this.kafka.consumer({
49
50
  groupId: this.options.groupId
50
51
  });
52
+ this.openTelemetryCollector = openTelemetryCollector;
51
53
  }
52
54
  async setupConsumer() {
53
55
  await this.consumer.connect();
@@ -163,8 +165,29 @@ var KafkaWorkerConsumer = class {
163
165
  }
164
166
  }
165
167
  async start() {
166
- await this.setupConsumer();
167
- await this.producer.connect();
168
+ const maxAttempts = 30;
169
+ const delayMs = 2e3;
170
+ let attempt = 1;
171
+ while (attempt <= maxAttempts) {
172
+ try {
173
+ await this.setupConsumer();
174
+ await this.producer.connect();
175
+ return;
176
+ } catch (error) {
177
+ const err = error;
178
+ const isUnknownTopic = err?.code === 3 || err?.type === "UNKNOWN_TOPIC_OR_PARTITION" || (err?.message || "").includes(
179
+ "This server does not host this topic-partition"
180
+ );
181
+ if (!isUnknownTopic || attempt >= maxAttempts) {
182
+ throw error;
183
+ }
184
+ this.openTelemetryCollector.warn(
185
+ `Kafka not ready for topic ${this.queueName} (attempt ${attempt}/${maxAttempts}). Retrying in ${delayMs}ms...`
186
+ );
187
+ await new Promise((r) => setTimeout(r, delayMs));
188
+ attempt += 1;
189
+ }
190
+ }
168
191
  }
169
192
  async close() {
170
193
  await this.producer.disconnect();
@@ -9,7 +9,8 @@ var KafkaWorkerConsumer = class {
9
9
  options;
10
10
  processEventsFunction;
11
11
  failureHandler;
12
- constructor(queueName, options, processEventsFunction, failureHandler) {
12
+ openTelemetryCollector;
13
+ constructor(queueName, options, processEventsFunction, failureHandler, openTelemetryCollector) {
13
14
  this.queueName = queueName;
14
15
  this.options = options;
15
16
  this.processEventsFunction = processEventsFunction;
@@ -22,6 +23,7 @@ var KafkaWorkerConsumer = class {
22
23
  this.consumer = this.kafka.consumer({
23
24
  groupId: this.options.groupId
24
25
  });
26
+ this.openTelemetryCollector = openTelemetryCollector;
25
27
  }
26
28
  async setupConsumer() {
27
29
  await this.consumer.connect();
@@ -137,8 +139,29 @@ var KafkaWorkerConsumer = class {
137
139
  }
138
140
  }
139
141
  async start() {
140
- await this.setupConsumer();
141
- await this.producer.connect();
142
+ const maxAttempts = 30;
143
+ const delayMs = 2e3;
144
+ let attempt = 1;
145
+ while (attempt <= maxAttempts) {
146
+ try {
147
+ await this.setupConsumer();
148
+ await this.producer.connect();
149
+ return;
150
+ } catch (error) {
151
+ const err = error;
152
+ const isUnknownTopic = err?.code === 3 || err?.type === "UNKNOWN_TOPIC_OR_PARTITION" || (err?.message || "").includes(
153
+ "This server does not host this topic-partition"
154
+ );
155
+ if (!isUnknownTopic || attempt >= maxAttempts) {
156
+ throw error;
157
+ }
158
+ this.openTelemetryCollector.warn(
159
+ `Kafka not ready for topic ${this.queueName} (attempt ${attempt}/${maxAttempts}). Retrying in ${delayMs}ms...`
160
+ );
161
+ await new Promise((r) => setTimeout(r, delayMs));
162
+ attempt += 1;
163
+ }
164
+ }
142
165
  }
143
166
  async close() {
144
167
  await this.producer.disconnect();
@@ -28,7 +28,7 @@ module.exports = __toCommonJS(schemas_exports);
28
28
  // domain/schemas/kafka.schema.ts
29
29
  var import_internal = require("@forklaunch/internal");
30
30
 
31
- // ../../../node_modules/.pnpm/@forklaunch+validator@0.10.21/node_modules/@forklaunch/validator/lib/src/typebox/index.mjs
31
+ // ../../../node_modules/.pnpm/@forklaunch+validator@0.10.22/node_modules/@forklaunch/validator/lib/src/typebox/index.mjs
32
32
  var typebox_exports = {};
33
33
  __export(typebox_exports, {
34
34
  SchemaValidator: () => SchemaValidator,
@@ -68,7 +68,7 @@ __export(typebox_exports, {
68
68
  });
69
69
  __reExport(typebox_exports, require("@sinclair/typebox"));
70
70
 
71
- // ../../../node_modules/.pnpm/@forklaunch+common@0.6.21/node_modules/@forklaunch/common/lib/index.mjs
71
+ // ../../../node_modules/.pnpm/@forklaunch+common@0.6.22/node_modules/@forklaunch/common/lib/index.mjs
72
72
  function deepCloneWithoutUndefined(obj, seen = /* @__PURE__ */ new WeakMap()) {
73
73
  if (obj === null || obj === void 0) {
74
74
  return obj;
@@ -148,7 +148,7 @@ var InMemoryBlob = class extends Blob {
148
148
  }
149
149
  };
150
150
 
151
- // ../../../node_modules/.pnpm/@forklaunch+validator@0.10.21/node_modules/@forklaunch/validator/lib/src/typebox/index.mjs
151
+ // ../../../node_modules/.pnpm/@forklaunch+validator@0.10.22/node_modules/@forklaunch/validator/lib/src/typebox/index.mjs
152
152
  var import_typebox = require("@sinclair/typebox");
153
153
  var import_compiler = require("@sinclair/typebox/compiler");
154
154
  var import_errors = require("@sinclair/typebox/errors");
@@ -736,7 +736,7 @@ var KafkaWorkerOptionsSchema = {
736
736
  peekCount: number
737
737
  };
738
738
 
739
- // ../../../node_modules/.pnpm/@forklaunch+validator@0.10.21/node_modules/@forklaunch/validator/lib/src/zod/index.mjs
739
+ // ../../../node_modules/.pnpm/@forklaunch+validator@0.10.22/node_modules/@forklaunch/validator/lib/src/zod/index.mjs
740
740
  var import_v3 = require("zod/v3");
741
741
 
742
742
  // ../../../node_modules/.pnpm/ts-deepmerge@7.0.3/node_modules/ts-deepmerge/esm/index.js
@@ -786,7 +786,7 @@ merge.withOptions = (options, ...objects) => {
786
786
  return result;
787
787
  };
788
788
 
789
- // ../../../node_modules/.pnpm/@forklaunch+validator@0.10.21/node_modules/@forklaunch/validator/lib/src/zod/index.mjs
789
+ // ../../../node_modules/.pnpm/@forklaunch+validator@0.10.22/node_modules/@forklaunch/validator/lib/src/zod/index.mjs
790
790
  var import_v32 = require("zod/v3");
791
791
  function extendApi(schema, schemaObject = {}) {
792
792
  const This = schema.constructor;
@@ -19,7 +19,7 @@ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "defau
19
19
  // domain/schemas/kafka.schema.ts
20
20
  import { serviceSchemaResolver } from "@forklaunch/internal";
21
21
 
22
- // ../../../node_modules/.pnpm/@forklaunch+validator@0.10.21/node_modules/@forklaunch/validator/lib/src/typebox/index.mjs
22
+ // ../../../node_modules/.pnpm/@forklaunch+validator@0.10.22/node_modules/@forklaunch/validator/lib/src/typebox/index.mjs
23
23
  var typebox_exports = {};
24
24
  __export(typebox_exports, {
25
25
  SchemaValidator: () => SchemaValidator,
@@ -60,7 +60,7 @@ __export(typebox_exports, {
60
60
  __reExport(typebox_exports, typebox_star);
61
61
  import * as typebox_star from "@sinclair/typebox";
62
62
 
63
- // ../../../node_modules/.pnpm/@forklaunch+common@0.6.21/node_modules/@forklaunch/common/lib/index.mjs
63
+ // ../../../node_modules/.pnpm/@forklaunch+common@0.6.22/node_modules/@forklaunch/common/lib/index.mjs
64
64
  function deepCloneWithoutUndefined(obj, seen = /* @__PURE__ */ new WeakMap()) {
65
65
  if (obj === null || obj === void 0) {
66
66
  return obj;
@@ -140,7 +140,7 @@ var InMemoryBlob = class extends Blob {
140
140
  }
141
141
  };
142
142
 
143
- // ../../../node_modules/.pnpm/@forklaunch+validator@0.10.21/node_modules/@forklaunch/validator/lib/src/typebox/index.mjs
143
+ // ../../../node_modules/.pnpm/@forklaunch+validator@0.10.22/node_modules/@forklaunch/validator/lib/src/typebox/index.mjs
144
144
  import {
145
145
  FormatRegistry,
146
146
  Kind,
@@ -738,7 +738,7 @@ var KafkaWorkerOptionsSchema = {
738
738
  peekCount: number
739
739
  };
740
740
 
741
- // ../../../node_modules/.pnpm/@forklaunch+validator@0.10.21/node_modules/@forklaunch/validator/lib/src/zod/index.mjs
741
+ // ../../../node_modules/.pnpm/@forklaunch+validator@0.10.22/node_modules/@forklaunch/validator/lib/src/zod/index.mjs
742
742
  import {
743
743
  z as z2,
744
744
  ZodType
@@ -791,7 +791,7 @@ merge.withOptions = (options, ...objects) => {
791
791
  return result;
792
792
  };
793
793
 
794
- // ../../../node_modules/.pnpm/@forklaunch+validator@0.10.21/node_modules/@forklaunch/validator/lib/src/zod/index.mjs
794
+ // ../../../node_modules/.pnpm/@forklaunch+validator@0.10.22/node_modules/@forklaunch/validator/lib/src/zod/index.mjs
795
795
  import { z } from "zod/v3";
796
796
  function extendApi(schema, schemaObject = {}) {
797
797
  const This = schema.constructor;
@@ -1,3 +1,7 @@
1
+ import {
2
+ MetricsDefinition,
3
+ OpenTelemetryCollector
4
+ } from '@forklaunch/core/http';
1
5
  import { WorkerConsumer } from '@forklaunch/interfaces-worker/interfaces';
2
6
  import {
3
7
  WorkerEventEntity,
@@ -20,12 +24,14 @@ export class KafkaWorkerConsumer<
20
24
  protected readonly options: Options;
21
25
  protected readonly processEventsFunction: WorkerProcessFunction<EventEntity>;
22
26
  protected readonly failureHandler: WorkerFailureHandler<EventEntity>;
27
+ protected readonly openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>;
23
28
 
24
29
  constructor(
25
30
  queueName: string,
26
31
  options: Options,
27
32
  processEventsFunction: WorkerProcessFunction<EventEntity>,
28
- failureHandler: WorkerFailureHandler<EventEntity>
33
+ failureHandler: WorkerFailureHandler<EventEntity>,
34
+ openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>
29
35
  ) {
30
36
  this.queueName = queueName;
31
37
  this.options = options;
@@ -40,6 +46,7 @@ export class KafkaWorkerConsumer<
40
46
  this.consumer = this.kafka.consumer({
41
47
  groupId: this.options.groupId
42
48
  });
49
+ this.openTelemetryCollector = openTelemetryCollector;
43
50
  }
44
51
 
45
52
  private async setupConsumer() {
@@ -179,8 +186,39 @@ export class KafkaWorkerConsumer<
179
186
  }
180
187
 
181
188
  async start(): Promise<void> {
182
- await this.setupConsumer();
183
- await this.producer.connect();
189
+ const maxAttempts = 30;
190
+ const delayMs = 2000;
191
+ let attempt = 1;
192
+
193
+ while (attempt <= maxAttempts) {
194
+ try {
195
+ await this.setupConsumer();
196
+ await this.producer.connect();
197
+ return;
198
+ } catch (error) {
199
+ const err = error as Error & {
200
+ code?: number;
201
+ type?: string;
202
+ message?: string;
203
+ };
204
+ const isUnknownTopic =
205
+ err?.code === 3 ||
206
+ err?.type === 'UNKNOWN_TOPIC_OR_PARTITION' ||
207
+ (err?.message || '').includes(
208
+ 'This server does not host this topic-partition'
209
+ );
210
+
211
+ if (!isUnknownTopic || attempt >= maxAttempts) {
212
+ throw error;
213
+ }
214
+
215
+ this.openTelemetryCollector.warn(
216
+ `Kafka not ready for topic ${this.queueName} (attempt ${attempt}/${maxAttempts}). Retrying in ${delayMs}ms...`
217
+ );
218
+ await new Promise((r) => setTimeout(r, delayMs));
219
+ attempt += 1;
220
+ }
221
+ }
184
222
  }
185
223
 
186
224
  async close(): Promise<void> {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forklaunch/implementation-worker-kafka",
3
- "version": "0.8.5",
3
+ "version": "0.9.0",
4
4
  "description": "Kafka implementation for forklaunch workers",
5
5
  "homepage": "https://github.com/forklaunch/forklaunch-js#readme",
6
6
  "bugs": {
@@ -42,12 +42,12 @@
42
42
  "lib/**"
43
43
  ],
44
44
  "dependencies": {
45
- "@forklaunch/core": "^0.15.11",
46
- "@forklaunch/internal": "^0.3.21",
45
+ "@forklaunch/core": "^0.15.12",
46
+ "@forklaunch/internal": "^0.3.22",
47
47
  "@sinclair/typebox": "^0.34.41",
48
48
  "kafkajs": "^2.2.4",
49
49
  "zod": "^4.1.12",
50
- "@forklaunch/interfaces-worker": "0.7.5"
50
+ "@forklaunch/interfaces-worker": "0.7.6"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@typescript/native-preview": "7.0.0-dev.20251027.1",