@platformatic/kafka 2.3.1 → 2.4.0-alpha.1
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/dist/clients/consumer/consumer.js +106 -48
- package/dist/clients/consumer/options.d.ts +15 -0
- package/dist/clients/consumer/options.js +1 -0
- package/dist/clients/consumer/types.d.ts +3 -0
- package/dist/typescript-4/dist/clients/consumer/options.d.ts +15 -0
- package/dist/typescript-4/dist/clients/consumer/types.d.ts +3 -0
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -395,6 +395,10 @@ export class Consumer extends Base {
|
|
|
395
395
|
options.rebalanceTimeout ??= this[kOptions].rebalanceTimeout;
|
|
396
396
|
options.heartbeatInterval ??= this[kOptions].heartbeatInterval;
|
|
397
397
|
options.protocols ??= this[kOptions].protocols;
|
|
398
|
+
const protocolsMetadata = this[kOptions].protocolsMetadata;
|
|
399
|
+
if (!options.protocolsMetadata && protocolsMetadata) {
|
|
400
|
+
options.protocolsMetadata = protocolsMetadata;
|
|
401
|
+
}
|
|
398
402
|
this.#validateGroupOptions(options);
|
|
399
403
|
this.#membershipActive = true;
|
|
400
404
|
this.#joinGroup(options, callback);
|
|
@@ -1146,45 +1150,20 @@ export class Consumer extends Base {
|
|
|
1146
1150
|
return;
|
|
1147
1151
|
}
|
|
1148
1152
|
this.#cancelHeartbeat();
|
|
1149
|
-
|
|
1150
|
-
for (const protocol of options.protocols) {
|
|
1151
|
-
protocols.push({
|
|
1152
|
-
name: protocol.name,
|
|
1153
|
-
metadata: this.#encodeProtocolSubscriptionMetadata(protocol, this.topics.current)
|
|
1154
|
-
});
|
|
1155
|
-
}
|
|
1156
|
-
this.#performDeduplicateGroupOperaton('joinGroup', (connection, groupCallback) => {
|
|
1157
|
-
this[kGetApi]('JoinGroup', (error, api) => {
|
|
1158
|
-
if (error) {
|
|
1159
|
-
groupCallback(error);
|
|
1160
|
-
return;
|
|
1161
|
-
}
|
|
1162
|
-
api(connection, this.groupId, options.sessionTimeout, options.rebalanceTimeout, this.memberId ?? '', this.groupInstanceId, 'consumer', protocols, '', groupCallback);
|
|
1163
|
-
});
|
|
1164
|
-
}, (error, response) => {
|
|
1165
|
-
if (!this.#membershipActive) {
|
|
1166
|
-
callback(null);
|
|
1167
|
-
return;
|
|
1168
|
-
}
|
|
1153
|
+
this.#createJoinGroupProtocols(options, (error, protocols) => {
|
|
1169
1154
|
if (error) {
|
|
1170
|
-
if (this.#getRejoinError(error)) {
|
|
1171
|
-
this.#performJoinGroup(options, callback);
|
|
1172
|
-
return;
|
|
1173
|
-
}
|
|
1174
1155
|
callback(error);
|
|
1175
1156
|
return;
|
|
1176
1157
|
}
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
}
|
|
1186
|
-
// Send a syncGroup request
|
|
1187
|
-
this.#syncGroup(options.partitionAssigner, (error, response) => {
|
|
1158
|
+
this.#performDeduplicateGroupOperaton('joinGroup', (connection, groupCallback) => {
|
|
1159
|
+
this[kGetApi]('JoinGroup', (error, api) => {
|
|
1160
|
+
if (error) {
|
|
1161
|
+
groupCallback(error);
|
|
1162
|
+
return;
|
|
1163
|
+
}
|
|
1164
|
+
api(connection, this.groupId, options.sessionTimeout, options.rebalanceTimeout, this.memberId ?? '', this.groupInstanceId, 'consumer', protocols, '', groupCallback);
|
|
1165
|
+
});
|
|
1166
|
+
}, (error, response) => {
|
|
1188
1167
|
if (!this.#membershipActive) {
|
|
1189
1168
|
callback(null);
|
|
1190
1169
|
return;
|
|
@@ -1197,20 +1176,44 @@ export class Consumer extends Base {
|
|
|
1197
1176
|
callback(error);
|
|
1198
1177
|
return;
|
|
1199
1178
|
}
|
|
1200
|
-
|
|
1201
|
-
this
|
|
1202
|
-
this
|
|
1203
|
-
this.#
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1179
|
+
// This is for Azure Event Hubs compatibility, which does not respond with an error on the first join
|
|
1180
|
+
this.memberId = response.memberId;
|
|
1181
|
+
this.generationId = response.generationId;
|
|
1182
|
+
this.#isLeader = response.leader === this.memberId;
|
|
1183
|
+
this.#protocol = response.protocolName;
|
|
1184
|
+
this.#members = new Map();
|
|
1185
|
+
for (const member of response.members) {
|
|
1186
|
+
this.#members.set(member.memberId, this.#decodeProtocolSubscriptionMetadata(member.memberId, member.metadata));
|
|
1187
|
+
}
|
|
1188
|
+
// Send a syncGroup request
|
|
1189
|
+
this.#syncGroup(options.partitionAssigner, (error, response) => {
|
|
1190
|
+
if (!this.#membershipActive) {
|
|
1191
|
+
callback(null);
|
|
1192
|
+
return;
|
|
1193
|
+
}
|
|
1194
|
+
if (error) {
|
|
1195
|
+
if (this.#getRejoinError(error)) {
|
|
1196
|
+
this.#performJoinGroup(options, callback);
|
|
1197
|
+
return;
|
|
1198
|
+
}
|
|
1199
|
+
callback(error);
|
|
1200
|
+
return;
|
|
1201
|
+
}
|
|
1202
|
+
this.assignments = response;
|
|
1203
|
+
this.#syncPreferredReadReplicas();
|
|
1204
|
+
this.#cancelHeartbeat();
|
|
1205
|
+
this.#heartbeatInterval = setTimeout(() => {
|
|
1206
|
+
this.#heartbeat(options);
|
|
1207
|
+
}, options.heartbeatInterval);
|
|
1208
|
+
this.emitWithDebug('consumer', 'group:join', {
|
|
1209
|
+
groupId: this.groupId,
|
|
1210
|
+
memberId: this.memberId,
|
|
1211
|
+
generationId: this.generationId,
|
|
1212
|
+
isLeader: this.#isLeader,
|
|
1213
|
+
assignments: this.assignments
|
|
1214
|
+
});
|
|
1215
|
+
callback(null, this.memberId);
|
|
1212
1216
|
});
|
|
1213
|
-
callback(null, this.memberId);
|
|
1214
1217
|
});
|
|
1215
1218
|
});
|
|
1216
1219
|
}
|
|
@@ -1370,6 +1373,61 @@ export class Consumer extends Base {
|
|
|
1370
1373
|
throw new UserError(this[kFormatValidationErrors](validator, '/options'));
|
|
1371
1374
|
}
|
|
1372
1375
|
}
|
|
1376
|
+
#createJoinGroupProtocols(options, callback) {
|
|
1377
|
+
if (typeof options.protocolsMetadata !== 'function') {
|
|
1378
|
+
callback(null, options.protocols.map(protocol => ({
|
|
1379
|
+
name: protocol.name,
|
|
1380
|
+
metadata: this.#encodeProtocolSubscriptionMetadata(protocol, this.topics.current)
|
|
1381
|
+
})));
|
|
1382
|
+
return;
|
|
1383
|
+
}
|
|
1384
|
+
this[kMetadata]({ topics: this.topics.current, forceUpdate: true }, (error, metadata) => {
|
|
1385
|
+
if (error) {
|
|
1386
|
+
callback(this.#handleError(error));
|
|
1387
|
+
return;
|
|
1388
|
+
}
|
|
1389
|
+
this.#resolveProtocolsMetadata(options.protocolsMetadata, options.protocols, this.topics.current, metadata, (error, userData) => {
|
|
1390
|
+
if (error) {
|
|
1391
|
+
callback(error);
|
|
1392
|
+
return;
|
|
1393
|
+
}
|
|
1394
|
+
else if (!Buffer.isBuffer(userData)) {
|
|
1395
|
+
callback(new UserError('protocolsMetadata must resolve to a Buffer.'));
|
|
1396
|
+
return;
|
|
1397
|
+
}
|
|
1398
|
+
callback(null, options.protocols.map(protocol => ({
|
|
1399
|
+
name: protocol.name,
|
|
1400
|
+
metadata: this.#encodeProtocolSubscriptionMetadata({ ...protocol, metadata: userData }, this.topics.current)
|
|
1401
|
+
})));
|
|
1402
|
+
});
|
|
1403
|
+
});
|
|
1404
|
+
}
|
|
1405
|
+
#resolveProtocolsMetadata(protocolsMetadata, protocols, topics, metadata, callback) {
|
|
1406
|
+
let settled = false;
|
|
1407
|
+
function resolveCallback(error, userData) {
|
|
1408
|
+
if (settled) {
|
|
1409
|
+
return;
|
|
1410
|
+
}
|
|
1411
|
+
settled = true;
|
|
1412
|
+
callback(error, userData);
|
|
1413
|
+
}
|
|
1414
|
+
let result;
|
|
1415
|
+
try {
|
|
1416
|
+
result = protocolsMetadata(protocols, topics, metadata, resolveCallback);
|
|
1417
|
+
if (typeof result !== 'undefined') {
|
|
1418
|
+
if (typeof result.then === 'function') {
|
|
1419
|
+
;
|
|
1420
|
+
result.then(userData => process.nextTick(resolveCallback, null, userData), error => process.nextTick(resolveCallback, error));
|
|
1421
|
+
}
|
|
1422
|
+
else {
|
|
1423
|
+
resolveCallback(null, result);
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
catch (error) {
|
|
1428
|
+
resolveCallback(error);
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1373
1431
|
/*
|
|
1374
1432
|
The following two methods follow:
|
|
1375
1433
|
https://github.com/apache/kafka/blob/trunk/clients/src/main/resources/common/message/ConsumerProtocolSubscription.json
|
|
@@ -53,6 +53,9 @@ export declare const groupOptionsProperties: {
|
|
|
53
53
|
};
|
|
54
54
|
};
|
|
55
55
|
};
|
|
56
|
+
protocolsMetadata: {
|
|
57
|
+
function: boolean;
|
|
58
|
+
};
|
|
56
59
|
partitionAssigner: {
|
|
57
60
|
function: boolean;
|
|
58
61
|
};
|
|
@@ -195,6 +198,9 @@ export declare const groupOptionsSchema: {
|
|
|
195
198
|
};
|
|
196
199
|
};
|
|
197
200
|
};
|
|
201
|
+
protocolsMetadata: {
|
|
202
|
+
function: boolean;
|
|
203
|
+
};
|
|
198
204
|
partitionAssigner: {
|
|
199
205
|
function: boolean;
|
|
200
206
|
};
|
|
@@ -315,6 +321,9 @@ export declare const consumeOptionsSchema: {
|
|
|
315
321
|
};
|
|
316
322
|
};
|
|
317
323
|
};
|
|
324
|
+
protocolsMetadata: {
|
|
325
|
+
function: boolean;
|
|
326
|
+
};
|
|
318
327
|
partitionAssigner: {
|
|
319
328
|
function: boolean;
|
|
320
329
|
};
|
|
@@ -481,6 +490,9 @@ export declare const consumerOptionsSchema: {
|
|
|
481
490
|
};
|
|
482
491
|
};
|
|
483
492
|
};
|
|
493
|
+
protocolsMetadata: {
|
|
494
|
+
function: boolean;
|
|
495
|
+
};
|
|
484
496
|
partitionAssigner: {
|
|
485
497
|
function: boolean;
|
|
486
498
|
};
|
|
@@ -608,6 +620,9 @@ export declare const fetchOptionsSchema: {
|
|
|
608
620
|
};
|
|
609
621
|
};
|
|
610
622
|
};
|
|
623
|
+
protocolsMetadata: {
|
|
624
|
+
function: boolean;
|
|
625
|
+
};
|
|
611
626
|
partitionAssigner: {
|
|
612
627
|
function: boolean;
|
|
613
628
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Callback } from '../../apis/definitions.ts';
|
|
1
2
|
import { type FetchRequestTopic } from '../../apis/consumer/fetch-v17.ts';
|
|
2
3
|
import { type GroupProtocols } from '../../apis/enumerations.ts';
|
|
3
4
|
import { type ConnectionPool } from '../../network/connection-pool.ts';
|
|
@@ -33,6 +34,7 @@ export interface PreferredReadReplica {
|
|
|
33
34
|
}
|
|
34
35
|
export type CorruptedMessageHandler = (record: KafkaRecord, topic: string, partition: number, firstTimestamp: bigint, firstOffset: bigint, commit: Message['commit']) => boolean;
|
|
35
36
|
export type GroupPartitionsAssigner = (current: string, members: Map<string, ExtendedGroupProtocolSubscription>, topics: Set<string>, metadata: ClusterMetadata) => GroupPartitionsAssignments[];
|
|
37
|
+
export type GroupProtocolsMetadataCallback = (protocols: GroupProtocolSubscription[], topics: string[], metadata: ClusterMetadata, callback: Callback<Buffer>) => Buffer | Promise<Buffer> | undefined;
|
|
36
38
|
export declare const MessagesStreamModes: {
|
|
37
39
|
readonly LATEST: "latest";
|
|
38
40
|
readonly EARLIEST: "earliest";
|
|
@@ -57,6 +59,7 @@ export interface GroupOptions {
|
|
|
57
59
|
rebalanceTimeout?: number;
|
|
58
60
|
heartbeatInterval?: number;
|
|
59
61
|
protocols?: GroupProtocolSubscription[];
|
|
62
|
+
protocolsMetadata?: GroupProtocolsMetadataCallback;
|
|
60
63
|
partitionAssigner?: GroupPartitionsAssigner;
|
|
61
64
|
assignmentUserData?: Buffer;
|
|
62
65
|
}
|
|
@@ -53,6 +53,9 @@ export declare const groupOptionsProperties: {
|
|
|
53
53
|
};
|
|
54
54
|
};
|
|
55
55
|
};
|
|
56
|
+
protocolsMetadata: {
|
|
57
|
+
function: boolean;
|
|
58
|
+
};
|
|
56
59
|
partitionAssigner: {
|
|
57
60
|
function: boolean;
|
|
58
61
|
};
|
|
@@ -195,6 +198,9 @@ export declare const groupOptionsSchema: {
|
|
|
195
198
|
};
|
|
196
199
|
};
|
|
197
200
|
};
|
|
201
|
+
protocolsMetadata: {
|
|
202
|
+
function: boolean;
|
|
203
|
+
};
|
|
198
204
|
partitionAssigner: {
|
|
199
205
|
function: boolean;
|
|
200
206
|
};
|
|
@@ -315,6 +321,9 @@ export declare const consumeOptionsSchema: {
|
|
|
315
321
|
};
|
|
316
322
|
};
|
|
317
323
|
};
|
|
324
|
+
protocolsMetadata: {
|
|
325
|
+
function: boolean;
|
|
326
|
+
};
|
|
318
327
|
partitionAssigner: {
|
|
319
328
|
function: boolean;
|
|
320
329
|
};
|
|
@@ -481,6 +490,9 @@ export declare const consumerOptionsSchema: {
|
|
|
481
490
|
};
|
|
482
491
|
};
|
|
483
492
|
};
|
|
493
|
+
protocolsMetadata: {
|
|
494
|
+
function: boolean;
|
|
495
|
+
};
|
|
484
496
|
partitionAssigner: {
|
|
485
497
|
function: boolean;
|
|
486
498
|
};
|
|
@@ -608,6 +620,9 @@ export declare const fetchOptionsSchema: {
|
|
|
608
620
|
};
|
|
609
621
|
};
|
|
610
622
|
};
|
|
623
|
+
protocolsMetadata: {
|
|
624
|
+
function: boolean;
|
|
625
|
+
};
|
|
611
626
|
partitionAssigner: {
|
|
612
627
|
function: boolean;
|
|
613
628
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Callback } from "../../apis/definitions";
|
|
1
2
|
import { type FetchRequestTopic } from "../../apis/consumer/fetch-v17";
|
|
2
3
|
import { type GroupProtocols } from "../../apis/enumerations";
|
|
3
4
|
import { type ConnectionPool } from "../../network/connection-pool";
|
|
@@ -33,6 +34,7 @@ export interface PreferredReadReplica {
|
|
|
33
34
|
}
|
|
34
35
|
export type CorruptedMessageHandler = (record: KafkaRecord, topic: string, partition: number, firstTimestamp: bigint, firstOffset: bigint, commit: Message['commit']) => boolean;
|
|
35
36
|
export type GroupPartitionsAssigner = (current: string, members: Map<string, ExtendedGroupProtocolSubscription>, topics: Set<string>, metadata: ClusterMetadata) => GroupPartitionsAssignments[];
|
|
37
|
+
export type GroupProtocolsMetadataCallback = (protocols: GroupProtocolSubscription[], topics: string[], metadata: ClusterMetadata, callback: Callback<Buffer>) => Buffer | Promise<Buffer> | undefined;
|
|
36
38
|
export declare const MessagesStreamModes: {
|
|
37
39
|
readonly LATEST: "latest";
|
|
38
40
|
readonly EARLIEST: "earliest";
|
|
@@ -57,6 +59,7 @@ export interface GroupOptions {
|
|
|
57
59
|
rebalanceTimeout?: number;
|
|
58
60
|
heartbeatInterval?: number;
|
|
59
61
|
protocols?: GroupProtocolSubscription[];
|
|
62
|
+
protocolsMetadata?: GroupProtocolsMetadataCallback;
|
|
60
63
|
partitionAssigner?: GroupPartitionsAssigner;
|
|
61
64
|
assignmentUserData?: Buffer;
|
|
62
65
|
}
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export const name = "@platformatic/kafka";
|
|
2
|
-
export const version = "2.
|
|
2
|
+
export const version = "2.4.0-alpha.1";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/kafka",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0-alpha.1",
|
|
4
4
|
"description": "Modern and performant client for Apache Kafka",
|
|
5
5
|
"homepage": "https://github.com/platformatic/kafka",
|
|
6
6
|
"author": "Platformatic Inc. <oss@platformatic.dev> (https://platformatic.dev)",
|