@platformatic/kafka 1.29.0 → 1.31.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/README.md +1 -1
- package/dist/apis/admin/alter-partition-reassignments-v0.d.ts +2 -2
- package/dist/apis/admin/alter-partition-reassignments-v0.js +1 -1
- package/dist/apis/admin/alter-partition-reassignments-v1.d.ts +30 -0
- package/dist/apis/admin/alter-partition-reassignments-v1.js +71 -0
- package/dist/apis/admin/index.d.ts +2 -0
- package/dist/apis/admin/index.js +2 -0
- package/dist/apis/admin/list-transactions-v0.d.ts +3 -2
- package/dist/apis/admin/list-transactions-v0.js +1 -1
- package/dist/apis/admin/list-transactions-v1.d.ts +3 -2
- package/dist/apis/admin/list-transactions-v1.js +1 -1
- package/dist/apis/admin/list-transactions-v2.d.ts +20 -0
- package/dist/apis/admin/list-transactions-v2.js +49 -0
- package/dist/apis/callbacks.js +1 -1
- package/dist/apis/consumer/consumer-group-heartbeat-v0.d.ts +2 -2
- package/dist/apis/consumer/consumer-group-heartbeat-v0.js +1 -1
- package/dist/apis/consumer/consumer-group-heartbeat-v1.d.ts +27 -0
- package/dist/apis/consumer/consumer-group-heartbeat-v1.js +70 -0
- package/dist/apis/consumer/index.d.ts +1 -0
- package/dist/apis/consumer/index.js +1 -0
- package/dist/clients/admin/admin.d.ts +3 -1
- package/dist/clients/admin/admin.js +63 -35
- package/dist/clients/admin/options.d.ts +22 -0
- package/dist/clients/admin/options.js +15 -1
- package/dist/clients/admin/types.d.ts +11 -1
- package/dist/clients/base/base.d.ts +4 -1
- package/dist/clients/base/base.js +17 -2
- package/dist/clients/base/index.d.ts +1 -1
- package/dist/clients/base/index.js +1 -1
- package/dist/clients/base/options.d.ts +1 -0
- package/dist/clients/base/options.js +1 -0
- package/dist/clients/base/types.d.ts +1 -0
- package/dist/clients/consumer/consumer.d.ts +4 -1
- package/dist/clients/consumer/consumer.js +46 -5
- package/dist/clients/consumer/messages-stream.d.ts +1 -0
- package/dist/clients/consumer/messages-stream.js +65 -15
- package/dist/clients/consumer/options.d.ts +3 -0
- package/dist/clients/consumer/options.js +3 -0
- package/dist/clients/consumer/types.d.ts +3 -0
- package/dist/clients/producer/producer.js +13 -3
- package/dist/errors.js +9 -1
- package/dist/network/connection-pool.d.ts +2 -0
- package/dist/network/connection-pool.js +11 -2
- package/dist/network/connection.d.ts +3 -0
- package/dist/network/connection.js +34 -4
- package/dist/registries/abstract.js +4 -0
- package/dist/typescript-4/dist/apis/admin/alter-partition-reassignments-v0.d.ts +2 -2
- package/dist/typescript-4/dist/apis/admin/alter-partition-reassignments-v1.d.ts +30 -0
- package/dist/typescript-4/dist/apis/admin/index.d.ts +2 -0
- package/dist/typescript-4/dist/apis/admin/list-transactions-v0.d.ts +3 -2
- package/dist/typescript-4/dist/apis/admin/list-transactions-v1.d.ts +3 -2
- package/dist/typescript-4/dist/apis/admin/list-transactions-v2.d.ts +20 -0
- package/dist/typescript-4/dist/apis/consumer/consumer-group-heartbeat-v0.d.ts +2 -2
- package/dist/typescript-4/dist/apis/consumer/consumer-group-heartbeat-v1.d.ts +27 -0
- package/dist/typescript-4/dist/apis/consumer/index.d.ts +1 -0
- package/dist/typescript-4/dist/clients/admin/admin.d.ts +3 -1
- package/dist/typescript-4/dist/clients/admin/options.d.ts +22 -0
- package/dist/typescript-4/dist/clients/admin/types.d.ts +11 -1
- package/dist/typescript-4/dist/clients/base/base.d.ts +4 -1
- package/dist/typescript-4/dist/clients/base/index.d.ts +1 -1
- package/dist/typescript-4/dist/clients/base/options.d.ts +1 -0
- package/dist/typescript-4/dist/clients/base/types.d.ts +1 -0
- package/dist/typescript-4/dist/clients/consumer/consumer.d.ts +4 -1
- package/dist/typescript-4/dist/clients/consumer/messages-stream.d.ts +1 -0
- package/dist/typescript-4/dist/clients/consumer/options.d.ts +3 -0
- package/dist/typescript-4/dist/clients/consumer/types.d.ts +3 -0
- package/dist/typescript-4/dist/network/connection-pool.d.ts +2 -0
- package/dist/typescript-4/dist/network/connection.d.ts +3 -0
- package/dist/version.js +1 -1
- package/package.json +2 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { createPromisifiedCallback, kCallbackPromise, runConcurrentCallbacks } from "../../apis/callbacks.js";
|
|
2
2
|
import { ConfigResourceTypes, FetchIsolationLevels, FindCoordinatorKeyTypes } from "../../apis/enumerations.js";
|
|
3
3
|
import { adminAclsChannel, adminClientQuotasChannel, adminConfigsChannel, adminConsumerGroupOffsetsChannel, adminGroupsChannel, adminLogDirsChannel, adminOffsetsChannel, adminTopicsChannel, createDiagnosticContext } from "../../diagnostic.js";
|
|
4
|
-
import { MultipleErrors } from "../../errors.js";
|
|
4
|
+
import { MultipleErrors, UserError } from "../../errors.js";
|
|
5
5
|
import { Reader } from "../../protocol/reader.js";
|
|
6
6
|
import { Base, kAfterCreate, kCheckNotClosed, kConnections, kGetApi, kGetBootstrapConnection, kGetConnection, kMetadata, kOptions, kPerformDeduplicated, kPerformWithRetry, kValidateOptions } from "../base/base.js";
|
|
7
|
-
import { adminListOffsetsOptionsValidator, alterClientQuotasOptionsValidator, alterConfigsOptionsValidator, alterConsumerGroupOffsetsOptionsValidator, createAclsOptionsValidator, createPartitionsOptionsValidator, createTopicsOptionsValidator, deleteAclsOptionsValidator, deleteConsumerGroupOffsetsOptionsValidator, deleteRecordsOptionsValidator, deleteGroupsOptionsValidator, deleteTopicsOptionsValidator, describeAclsOptionsValidator, describeClientQuotasOptionsValidator, describeConfigsOptionsValidator, describeGroupsOptionsValidator, describeLogDirsOptionsValidator, incrementalAlterConfigsOptionsValidator, listConsumerGroupOffsetsOptionsValidator, listGroupsOptionsValidator, listTopicsOptionsValidator, removeMembersFromConsumerGroupOptionsValidator } from "./options.js";
|
|
7
|
+
import { adminListOffsetsOptionsValidator, alterClientQuotasOptionsValidator, alterConfigsOptionsValidator, alterConsumerGroupOffsetsOptionsValidator, createAclsOptionsValidator, createPartitionsOptionsValidator, createTopicsOptionsValidator, deleteAclsOptionsValidator, deleteConsumerGroupOffsetsOptionsValidator, deleteRecordsOptionsValidator, deleteGroupsOptionsValidator, deleteTopicsOptionsValidator, describeAclsOptionsValidator, describeClientQuotasOptionsValidator, describeConfigsOptionsValidator, describeGroupsOptionsValidator, describeLogDirsOptionsValidator, findCoordinatorOptionsValidator, incrementalAlterConfigsOptionsValidator, listConsumerGroupOffsetsOptionsValidator, listGroupsOptionsValidator, listTopicsOptionsValidator, removeMembersFromConsumerGroupOptionsValidator } from "./options.js";
|
|
8
8
|
export class Admin extends Base {
|
|
9
9
|
#controller = null;
|
|
10
10
|
constructor(options) {
|
|
@@ -108,6 +108,21 @@ export class Admin extends Base {
|
|
|
108
108
|
adminGroupsChannel.traceCallback(this.#describeGroups, 1, createDiagnosticContext({ client: this, operation: 'describeGroups', options }), this, options, callback);
|
|
109
109
|
return callback[kCallbackPromise];
|
|
110
110
|
}
|
|
111
|
+
findCoordinator(options, callback) {
|
|
112
|
+
if (!callback) {
|
|
113
|
+
callback = createPromisifiedCallback();
|
|
114
|
+
}
|
|
115
|
+
if (this[kCheckNotClosed](callback)) {
|
|
116
|
+
return callback[kCallbackPromise];
|
|
117
|
+
}
|
|
118
|
+
const validationError = this[kValidateOptions](options, findCoordinatorOptionsValidator, '/options', false);
|
|
119
|
+
if (validationError) {
|
|
120
|
+
callback(validationError);
|
|
121
|
+
return callback[kCallbackPromise];
|
|
122
|
+
}
|
|
123
|
+
adminGroupsChannel.traceCallback(this.#findCoordinator, 1, createDiagnosticContext({ client: this, operation: 'findCoordinator', options }), this, options, callback);
|
|
124
|
+
return callback[kCallbackPromise];
|
|
125
|
+
}
|
|
111
126
|
deleteGroups(options, callback) {
|
|
112
127
|
if (!callback) {
|
|
113
128
|
callback = createPromisifiedCallback();
|
|
@@ -563,22 +578,22 @@ export class Admin extends Base {
|
|
|
563
578
|
callback(error);
|
|
564
579
|
return;
|
|
565
580
|
}
|
|
566
|
-
this.#
|
|
581
|
+
this.#findCoordinator({ keyType: FindCoordinatorKeyTypes.GROUP, keys: options.groups }, (error, coordinators) => {
|
|
567
582
|
if (error) {
|
|
568
583
|
callback(error);
|
|
569
584
|
return;
|
|
570
585
|
}
|
|
571
586
|
// Group the groups by coordinator
|
|
572
|
-
const
|
|
573
|
-
for (const { key: group, nodeId: node } of
|
|
574
|
-
let coordinator =
|
|
587
|
+
const coordinatorsMap = new Map();
|
|
588
|
+
for (const { key: group, nodeId: node } of coordinators) {
|
|
589
|
+
let coordinator = coordinatorsMap.get(node);
|
|
575
590
|
if (!coordinator) {
|
|
576
591
|
coordinator = [];
|
|
577
|
-
|
|
592
|
+
coordinatorsMap.set(node, coordinator);
|
|
578
593
|
}
|
|
579
594
|
coordinator.push(group);
|
|
580
595
|
}
|
|
581
|
-
runConcurrentCallbacks('Describing groups failed.',
|
|
596
|
+
runConcurrentCallbacks('Describing groups failed.', coordinatorsMap, ([node, groups], concurrentCallback) => {
|
|
582
597
|
this[kGetConnection](metadata.brokers.get(node), (error, connection) => {
|
|
583
598
|
if (error) {
|
|
584
599
|
concurrentCallback(error);
|
|
@@ -651,22 +666,22 @@ export class Admin extends Base {
|
|
|
651
666
|
callback(error);
|
|
652
667
|
return;
|
|
653
668
|
}
|
|
654
|
-
this.#
|
|
669
|
+
this.#findCoordinator({ keyType: FindCoordinatorKeyTypes.GROUP, keys: options.groups }, (error, coordinators) => {
|
|
655
670
|
if (error) {
|
|
656
671
|
callback(error);
|
|
657
672
|
return;
|
|
658
673
|
}
|
|
659
674
|
// Group the groups by coordinator
|
|
660
|
-
const
|
|
661
|
-
for (const { key: group, nodeId: node } of
|
|
662
|
-
let coordinator =
|
|
675
|
+
const coordinatorsMap = new Map();
|
|
676
|
+
for (const { key: group, nodeId: node } of coordinators) {
|
|
677
|
+
let coordinator = coordinatorsMap.get(node);
|
|
663
678
|
if (!coordinator) {
|
|
664
679
|
coordinator = [];
|
|
665
|
-
|
|
680
|
+
coordinatorsMap.set(node, coordinator);
|
|
666
681
|
}
|
|
667
682
|
coordinator.push(group);
|
|
668
683
|
}
|
|
669
|
-
runConcurrentCallbacks('Deleting groups failed.',
|
|
684
|
+
runConcurrentCallbacks('Deleting groups failed.', coordinatorsMap, ([node, groups], concurrentCallback) => {
|
|
670
685
|
this[kGetConnection](metadata.brokers.get(node), (error, connection) => {
|
|
671
686
|
if (error) {
|
|
672
687
|
concurrentCallback(error);
|
|
@@ -714,12 +729,12 @@ export class Admin extends Base {
|
|
|
714
729
|
callback(error, undefined);
|
|
715
730
|
return;
|
|
716
731
|
}
|
|
717
|
-
this.#
|
|
732
|
+
this.#findCoordinator({ keyType: FindCoordinatorKeyTypes.GROUP, keys: [options.groupId] }, (error, coordinators) => {
|
|
718
733
|
if (error) {
|
|
719
734
|
callback(new MultipleErrors('Removing members from consumer group failed.', [error]));
|
|
720
735
|
return;
|
|
721
736
|
}
|
|
722
|
-
const coordinator =
|
|
737
|
+
const coordinator = coordinators.find(c => c.key === options.groupId);
|
|
723
738
|
/* c8 ignore next 8 - Hard to test */
|
|
724
739
|
if (!coordinator) {
|
|
725
740
|
callback(new MultipleErrors('Removing members from consumer group failed.', [
|
|
@@ -765,8 +780,8 @@ export class Admin extends Base {
|
|
|
765
780
|
});
|
|
766
781
|
});
|
|
767
782
|
}
|
|
768
|
-
#
|
|
769
|
-
this[kPerformWithRetry]('
|
|
783
|
+
#findCoordinator(options, callback) {
|
|
784
|
+
this[kPerformWithRetry]('findCoordinator', retryCallback => {
|
|
770
785
|
this[kGetBootstrapConnection]((error, connection) => {
|
|
771
786
|
if (error) {
|
|
772
787
|
retryCallback(error);
|
|
@@ -777,7 +792,7 @@ export class Admin extends Base {
|
|
|
777
792
|
retryCallback(error);
|
|
778
793
|
return;
|
|
779
794
|
}
|
|
780
|
-
api(connection,
|
|
795
|
+
api(connection, options.keyType, options.keys, retryCallback);
|
|
781
796
|
});
|
|
782
797
|
});
|
|
783
798
|
}, (error, response) => {
|
|
@@ -785,7 +800,12 @@ export class Admin extends Base {
|
|
|
785
800
|
callback(error);
|
|
786
801
|
return;
|
|
787
802
|
}
|
|
788
|
-
callback(null, response
|
|
803
|
+
callback(null, response.coordinators.map(coordinator => ({
|
|
804
|
+
key: coordinator.key,
|
|
805
|
+
nodeId: coordinator.nodeId,
|
|
806
|
+
host: coordinator.host,
|
|
807
|
+
port: coordinator.port
|
|
808
|
+
})));
|
|
789
809
|
}, 0);
|
|
790
810
|
}
|
|
791
811
|
#describeClientQuotas(options, callback) {
|
|
@@ -883,13 +903,13 @@ export class Admin extends Base {
|
|
|
883
903
|
}
|
|
884
904
|
/* c8 ignore next - Hard to test */
|
|
885
905
|
const groupIds = options.groups.map(group => (typeof group === 'string' ? group : group.groupId));
|
|
886
|
-
this.#
|
|
906
|
+
this.#findCoordinator({ keyType: FindCoordinatorKeyTypes.GROUP, keys: groupIds }, (error, coordinators) => {
|
|
887
907
|
if (error) {
|
|
888
908
|
callback(new MultipleErrors('Listing consumer group offsets failed.', [error]));
|
|
889
909
|
return;
|
|
890
910
|
}
|
|
891
|
-
const
|
|
892
|
-
for (const { key: groupId, nodeId: node } of
|
|
911
|
+
const coordinatorsMap = new Map();
|
|
912
|
+
for (const { key: groupId, nodeId: node } of coordinators) {
|
|
893
913
|
const groupRequest = {
|
|
894
914
|
groupId,
|
|
895
915
|
memberId: null,
|
|
@@ -901,14 +921,14 @@ export class Admin extends Base {
|
|
|
901
921
|
break;
|
|
902
922
|
}
|
|
903
923
|
}
|
|
904
|
-
let coordinator =
|
|
924
|
+
let coordinator = coordinatorsMap.get(node);
|
|
905
925
|
if (!coordinator) {
|
|
906
926
|
coordinator = [];
|
|
907
|
-
|
|
927
|
+
coordinatorsMap.set(node, coordinator);
|
|
908
928
|
}
|
|
909
929
|
coordinator.push(groupRequest);
|
|
910
930
|
}
|
|
911
|
-
runConcurrentCallbacks('Listing consumer group offsets failed.',
|
|
931
|
+
runConcurrentCallbacks('Listing consumer group offsets failed.', coordinatorsMap, ([node, groups], concurrentCallback) => {
|
|
912
932
|
this[kGetConnection](metadata.brokers.get(node), (error, connection) => {
|
|
913
933
|
if (error) {
|
|
914
934
|
concurrentCallback(error);
|
|
@@ -952,12 +972,12 @@ export class Admin extends Base {
|
|
|
952
972
|
callback(error, undefined);
|
|
953
973
|
return;
|
|
954
974
|
}
|
|
955
|
-
this.#
|
|
975
|
+
this.#findCoordinator({ keyType: FindCoordinatorKeyTypes.GROUP, keys: [options.groupId] }, (error, coordinators) => {
|
|
956
976
|
if (error) {
|
|
957
977
|
callback(new MultipleErrors('Altering consumer group offsets failed.', [error]));
|
|
958
978
|
return;
|
|
959
979
|
}
|
|
960
|
-
const coordinator =
|
|
980
|
+
const coordinator = coordinators.find(c => c.key === options.groupId);
|
|
961
981
|
/* c8 ignore next 9 - Hard to test */
|
|
962
982
|
if (!coordinator) {
|
|
963
983
|
callback(new MultipleErrors('Altering consumer group offsets failed.', [
|
|
@@ -1013,12 +1033,12 @@ export class Admin extends Base {
|
|
|
1013
1033
|
callback(error);
|
|
1014
1034
|
return;
|
|
1015
1035
|
}
|
|
1016
|
-
this.#
|
|
1036
|
+
this.#findCoordinator({ keyType: FindCoordinatorKeyTypes.GROUP, keys: [options.groupId] }, (error, coordinators) => {
|
|
1017
1037
|
if (error) {
|
|
1018
1038
|
callback(new MultipleErrors('Deleting consumer group offsets failed.', [error]));
|
|
1019
1039
|
return;
|
|
1020
1040
|
}
|
|
1021
|
-
const coordinator =
|
|
1041
|
+
const coordinator = coordinators.find(c => c.key === options.groupId);
|
|
1022
1042
|
/* c8 ignore next 9 - Hard to test */
|
|
1023
1043
|
if (!coordinator) {
|
|
1024
1044
|
callback(new MultipleErrors('Deleting consumer group offsets failed.', [
|
|
@@ -1363,14 +1383,22 @@ export class Admin extends Base {
|
|
|
1363
1383
|
callback(error);
|
|
1364
1384
|
return;
|
|
1365
1385
|
}
|
|
1386
|
+
// metadata must be defined at this point
|
|
1387
|
+
const { topics, brokers } = metadata;
|
|
1366
1388
|
const requests = new Map();
|
|
1367
1389
|
for (const topic of options.topics) {
|
|
1368
1390
|
for (const partition of topic.partitions) {
|
|
1369
|
-
|
|
1370
|
-
|
|
1391
|
+
// topics.get(topic.name) must be defined as the metadata request was successful
|
|
1392
|
+
const topicData = topics.get(topic.name);
|
|
1393
|
+
const targetPartitionData = topicData.partitions[partition.partitionIndex];
|
|
1394
|
+
if (!targetPartitionData) {
|
|
1395
|
+
callback(new UserError(`Unknown partition ${partition.partitionIndex} for topic ${topic.name}.`));
|
|
1396
|
+
return;
|
|
1397
|
+
}
|
|
1398
|
+
let leaderRequests = requests.get(targetPartitionData.leader);
|
|
1371
1399
|
if (!leaderRequests) {
|
|
1372
1400
|
leaderRequests = [];
|
|
1373
|
-
requests.set(leader, leaderRequests);
|
|
1401
|
+
requests.set(targetPartitionData.leader, leaderRequests);
|
|
1374
1402
|
}
|
|
1375
1403
|
let topicRequest = leaderRequests.find(t => t.name === topic.name);
|
|
1376
1404
|
if (!topicRequest) {
|
|
@@ -1379,14 +1407,14 @@ export class Admin extends Base {
|
|
|
1379
1407
|
}
|
|
1380
1408
|
topicRequest.partitions.push({
|
|
1381
1409
|
partitionIndex: partition.partitionIndex,
|
|
1382
|
-
currentLeaderEpoch: leaderEpoch,
|
|
1410
|
+
currentLeaderEpoch: targetPartitionData.leaderEpoch,
|
|
1383
1411
|
/* c8 ignore next - Hard to test */
|
|
1384
1412
|
timestamp: partition.timestamp ?? -1n
|
|
1385
1413
|
});
|
|
1386
1414
|
}
|
|
1387
1415
|
}
|
|
1388
1416
|
runConcurrentCallbacks('Listing offsets failed.', requests, ([leader, requests], concurrentCallback) => {
|
|
1389
|
-
this[kGetConnection](
|
|
1417
|
+
this[kGetConnection](brokers.get(leader), (error, connection) => {
|
|
1390
1418
|
if (error) {
|
|
1391
1419
|
concurrentCallback(error);
|
|
1392
1420
|
return;
|
|
@@ -886,6 +886,25 @@ export declare const adminListOffsetsOptionsSchema: {
|
|
|
886
886
|
required: string[];
|
|
887
887
|
additionalProperties: boolean;
|
|
888
888
|
};
|
|
889
|
+
export declare const findCoordinatorOptionsSchema: {
|
|
890
|
+
type: string;
|
|
891
|
+
properties: {
|
|
892
|
+
keyType: {
|
|
893
|
+
type: string;
|
|
894
|
+
enum: (0 | 1 | 2)[];
|
|
895
|
+
};
|
|
896
|
+
keys: {
|
|
897
|
+
type: string;
|
|
898
|
+
items: {
|
|
899
|
+
type: string;
|
|
900
|
+
pattern: string;
|
|
901
|
+
};
|
|
902
|
+
minItems: number;
|
|
903
|
+
};
|
|
904
|
+
};
|
|
905
|
+
required: string[];
|
|
906
|
+
additionalProperties: boolean;
|
|
907
|
+
};
|
|
889
908
|
export declare const createTopicsOptionsValidator: import("ajv").ValidateFunction<{
|
|
890
909
|
[x: string]: {};
|
|
891
910
|
}>;
|
|
@@ -948,3 +967,6 @@ export declare const deleteAclsOptionsValidator: import("ajv").ValidateFunction<
|
|
|
948
967
|
export declare const adminListOffsetsOptionsValidator: import("ajv").ValidateFunction<{
|
|
949
968
|
[x: string]: {};
|
|
950
969
|
}>;
|
|
970
|
+
export declare const findCoordinatorOptionsValidator: import("ajv").ValidateFunction<{
|
|
971
|
+
[x: string]: {};
|
|
972
|
+
}>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { allowedAclOperations, allowedAclPermissionTypes, allowedClientQuotaMatchTypes, allowedFetchIsolationLevels, allowedIncrementalAlterConfigOperationTypes, allowedResourcePatternTypes, allowedResourceTypes, ConsumerGroupStates, IncrementalAlterConfigOperationTypes } from "../../apis/enumerations.js";
|
|
1
|
+
import { allowedAclOperations, allowedAclPermissionTypes, allowedClientQuotaMatchTypes, allowedFetchIsolationLevels, allowedFindCoordinatorKeyTypes, allowedIncrementalAlterConfigOperationTypes, allowedResourcePatternTypes, allowedResourceTypes, ConsumerGroupStates, IncrementalAlterConfigOperationTypes } from "../../apis/enumerations.js";
|
|
2
2
|
import { ajv, listErrorMessage } from "../../utils.js";
|
|
3
3
|
import { idProperty } from "../base/options.js";
|
|
4
4
|
export const groupsProperties = {
|
|
@@ -587,6 +587,19 @@ export const adminListOffsetsOptionsSchema = {
|
|
|
587
587
|
required: ['topics'],
|
|
588
588
|
additionalProperties: false
|
|
589
589
|
};
|
|
590
|
+
export const findCoordinatorOptionsSchema = {
|
|
591
|
+
type: 'object',
|
|
592
|
+
properties: {
|
|
593
|
+
keyType: { type: 'number', enum: [...allowedFindCoordinatorKeyTypes] },
|
|
594
|
+
keys: {
|
|
595
|
+
type: 'array',
|
|
596
|
+
items: idProperty,
|
|
597
|
+
minItems: 1
|
|
598
|
+
}
|
|
599
|
+
},
|
|
600
|
+
required: ['keyType', 'keys'],
|
|
601
|
+
additionalProperties: false
|
|
602
|
+
};
|
|
590
603
|
export const createTopicsOptionsValidator = ajv.compile(createTopicOptionsSchema);
|
|
591
604
|
export const createPartitionsOptionsValidator = ajv.compile(createPartitionsOptionsSchema);
|
|
592
605
|
export const listTopicsOptionsValidator = ajv.compile(listTopicOptionsSchema);
|
|
@@ -609,3 +622,4 @@ export const createAclsOptionsValidator = ajv.compile(createAclsOptionsSchema);
|
|
|
609
622
|
export const describeAclsOptionsValidator = ajv.compile(describeAclsOptionsSchema);
|
|
610
623
|
export const deleteAclsOptionsValidator = ajv.compile(deleteAclsOptionsSchema);
|
|
611
624
|
export const adminListOffsetsOptionsValidator = ajv.compile(adminListOffsetsOptionsSchema);
|
|
625
|
+
export const findCoordinatorOptionsValidator = ajv.compile(findCoordinatorOptionsSchema);
|
|
@@ -6,7 +6,7 @@ import { type DescribeClientQuotasRequestComponent } from '../../apis/admin/desc
|
|
|
6
6
|
import { type DescribeConfigsRequestResource, type DescribeConfigsResponseConfig } from '../../apis/admin/describe-configs-v4.ts';
|
|
7
7
|
import { type DescribeLogDirsRequestTopic, type DescribeLogDirsResponse, type DescribeLogDirsResponseResult } from '../../apis/admin/describe-log-dirs-v4.ts';
|
|
8
8
|
import { type IncrementalAlterConfigsRequestResource } from '../../apis/admin/incremental-alter-configs-v1.ts';
|
|
9
|
-
import { type ConfigResourceTypeValue, type ConsumerGroupStateValue, type FetchIsolationLevelValue } from '../../apis/enumerations.ts';
|
|
9
|
+
import { type ConfigResourceTypeValue, type ConsumerGroupStateValue, type FetchIsolationLevelValue, type FindCoordinatorKeyTypeValue } from '../../apis/enumerations.ts';
|
|
10
10
|
import { type Acl, type AclFilter } from '../../apis/types.ts';
|
|
11
11
|
import { type Nullable, type NullableString } from '../../protocol/definitions.ts';
|
|
12
12
|
import { type BaseOptions } from '../base/types.ts';
|
|
@@ -68,6 +68,16 @@ export interface DescribeGroupsOptions {
|
|
|
68
68
|
groups: string[];
|
|
69
69
|
includeAuthorizedOperations?: boolean;
|
|
70
70
|
}
|
|
71
|
+
export interface FindCoordinatorOptions {
|
|
72
|
+
keyType: FindCoordinatorKeyTypeValue;
|
|
73
|
+
keys: string[];
|
|
74
|
+
}
|
|
75
|
+
export interface FindCoordinatorResult {
|
|
76
|
+
key: string;
|
|
77
|
+
nodeId: number;
|
|
78
|
+
host: string;
|
|
79
|
+
port: number;
|
|
80
|
+
}
|
|
71
81
|
export interface DeleteGroupsOptions {
|
|
72
82
|
groups: string[];
|
|
73
83
|
}
|
|
@@ -30,6 +30,7 @@ export declare const kFormatValidationErrors: unique symbol;
|
|
|
30
30
|
export declare const kPrometheus: unique symbol;
|
|
31
31
|
export declare const kClientType: unique symbol;
|
|
32
32
|
export declare const kAfterCreate: unique symbol;
|
|
33
|
+
export declare const kContext: unique symbol;
|
|
33
34
|
export interface BaseEvents extends TypedEvents {
|
|
34
35
|
'client:broker:connect': (payload: ConnectionPoolEventPayload) => void;
|
|
35
36
|
'client:broker:disconnect': (payload: ConnectionPoolEventPayload) => void;
|
|
@@ -52,6 +53,7 @@ export declare class Base<OptionsType extends BaseOptions = BaseOptions, EventsT
|
|
|
52
53
|
[kInstance]: number;
|
|
53
54
|
[kClientId]: string;
|
|
54
55
|
[kClientType]: ClientType;
|
|
56
|
+
[kContext]: unknown;
|
|
55
57
|
[kBootstrapBrokers]: Broker[];
|
|
56
58
|
[kApis]: ApiVersionsResponseApi[];
|
|
57
59
|
[kOptions]: OptionsType;
|
|
@@ -63,6 +65,7 @@ export declare class Base<OptionsType extends BaseOptions = BaseOptions, EventsT
|
|
|
63
65
|
get clientId(): string;
|
|
64
66
|
get closed(): boolean;
|
|
65
67
|
get type(): ClientType;
|
|
68
|
+
get context(): unknown;
|
|
66
69
|
emitWithDebug(section: string | null, name: string, ...args: any[]): boolean;
|
|
67
70
|
close(callback: CallbackWithPromise<void>): void;
|
|
68
71
|
close(): Promise<void>;
|
|
@@ -74,7 +77,7 @@ export declare class Base<OptionsType extends BaseOptions = BaseOptions, EventsT
|
|
|
74
77
|
connectToBrokers(nodeIds?: number[] | null): Promise<Map<number, Connection>>;
|
|
75
78
|
isActive(): boolean;
|
|
76
79
|
isConnected(): boolean;
|
|
77
|
-
[kCreateConnectionPool](): ConnectionPool;
|
|
80
|
+
[kCreateConnectionPool](context?: unknown): ConnectionPool;
|
|
78
81
|
[kListApis](callback: CallbackWithPromise<ApiVersionsResponseApi[]>): void;
|
|
79
82
|
[kMetadata](options: MetadataOptions, callback: CallbackWithPromise<ClusterMetadata>): void;
|
|
80
83
|
[kCheckNotClosed](callback: CallbackWithPromise<any>): boolean;
|
|
@@ -30,6 +30,7 @@ export const kFormatValidationErrors = Symbol('plt.kafka.base.formatValidationEr
|
|
|
30
30
|
export const kPrometheus = Symbol('plt.kafka.base.prometheus');
|
|
31
31
|
export const kClientType = Symbol('plt.kafka.base.clientType');
|
|
32
32
|
export const kAfterCreate = Symbol('plt.kafka.base.afterCreate');
|
|
33
|
+
export const kContext = Symbol('plt.kafka.base.context');
|
|
33
34
|
let currentInstance = 0;
|
|
34
35
|
export class Base extends TypedEventEmitter {
|
|
35
36
|
// This is declared using a symbol (a.k.a protected/friend) to make it available in ConnectionPool and MessagesStream
|
|
@@ -37,6 +38,7 @@ export class Base extends TypedEventEmitter {
|
|
|
37
38
|
// General status - Use symbols rather than JS private property to make them "protected" as in C++
|
|
38
39
|
[kClientId];
|
|
39
40
|
[kClientType];
|
|
41
|
+
[kContext];
|
|
40
42
|
[kBootstrapBrokers];
|
|
41
43
|
[kApis];
|
|
42
44
|
[kOptions];
|
|
@@ -51,6 +53,7 @@ export class Base extends TypedEventEmitter {
|
|
|
51
53
|
this[kClientType] = 'base';
|
|
52
54
|
this[kInstance] = currentInstance++;
|
|
53
55
|
this[kApis] = [];
|
|
56
|
+
this[kContext] = options.context;
|
|
54
57
|
// Validate options
|
|
55
58
|
this[kOptions] = Object.assign({}, defaultBaseOptions, options);
|
|
56
59
|
this[kValidateOptions](this[kOptions], baseOptionsValidator, '/options');
|
|
@@ -84,6 +87,9 @@ export class Base extends TypedEventEmitter {
|
|
|
84
87
|
get type() {
|
|
85
88
|
return this[kClientType];
|
|
86
89
|
}
|
|
90
|
+
get context() {
|
|
91
|
+
return this[kContext];
|
|
92
|
+
}
|
|
87
93
|
emitWithDebug(section, name, ...args) {
|
|
88
94
|
if (!section) {
|
|
89
95
|
return this.emit(name, ...args);
|
|
@@ -170,10 +176,11 @@ export class Base extends TypedEventEmitter {
|
|
|
170
176
|
}
|
|
171
177
|
return this[kConnections].isConnected();
|
|
172
178
|
}
|
|
173
|
-
[kCreateConnectionPool]() {
|
|
179
|
+
[kCreateConnectionPool](context) {
|
|
174
180
|
const pool = new ConnectionPool(this[kClientId], {
|
|
181
|
+
...this[kOptions],
|
|
175
182
|
ownerId: this[kInstance],
|
|
176
|
-
|
|
183
|
+
context: context ?? this[kContext]
|
|
177
184
|
});
|
|
178
185
|
this.#forwardEvents(pool, [
|
|
179
186
|
'connect',
|
|
@@ -388,6 +395,14 @@ export class Base extends TypedEventEmitter {
|
|
|
388
395
|
});
|
|
389
396
|
}, (error, metadata) => {
|
|
390
397
|
if (error) {
|
|
398
|
+
const unknownTopicError = error.findBy('apiCode', 3);
|
|
399
|
+
if (unknownTopicError) {
|
|
400
|
+
const topicIndexMatch = unknownTopicError.path?.match(/\/topics\/(\d+)/);
|
|
401
|
+
const topicIndex = topicIndexMatch ? parseInt(topicIndexMatch[1]) : -1;
|
|
402
|
+
const topicName = topicIndex >= 0 && topicIndex < topicsToFetch.length ? topicsToFetch[topicIndex] : 'unknown';
|
|
403
|
+
deduplicateCallback(new UserError(`Unknown topic ${topicName}.`));
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
391
406
|
const hasStaleMetadata = error.findBy('hasStaleMetadata', true);
|
|
392
407
|
// Stale metadata, we need to fetch everything again
|
|
393
408
|
if (hasStaleMetadata) {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { Base, kCheckNotClosed, kGetApi, kGetBootstrapConnection, kGetConnection, kListApis, kMetadata, kOptions, kPerformDeduplicated, kPerformWithRetry, kValidateOptions } from './base.ts';
|
|
1
|
+
export { Base, kContext, kCheckNotClosed, kGetApi, kGetBootstrapConnection, kGetConnection, kListApis, kMetadata, kOptions, kPerformDeduplicated, kPerformWithRetry, kValidateOptions } from './base.ts';
|
|
2
2
|
export * from './options.ts';
|
|
3
3
|
export * from './types.ts';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { Base, kCheckNotClosed, kGetApi, kGetBootstrapConnection, kGetConnection, kListApis, kMetadata, kOptions, kPerformDeduplicated, kPerformWithRetry, kValidateOptions } from "./base.js";
|
|
1
|
+
export { Base, kContext, kCheckNotClosed, kGetApi, kGetBootstrapConnection, kGetConnection, kListApis, kMetadata, kOptions, kPerformDeduplicated, kPerformWithRetry, kValidateOptions } from "./base.js";
|
|
2
2
|
export * from "./options.js";
|
|
3
3
|
export * from "./types.js";
|
|
@@ -33,6 +33,7 @@ export type RetryDelayGetter<Owner = object> = (client: Owner, operationId: stri
|
|
|
33
33
|
export interface BaseOptions extends ConnectionOptions {
|
|
34
34
|
clientId: string;
|
|
35
35
|
bootstrapBrokers: Broker[] | string[];
|
|
36
|
+
context?: unknown;
|
|
36
37
|
timeout?: number;
|
|
37
38
|
retries?: number | boolean;
|
|
38
39
|
retryDelay?: number | RetryDelayGetter;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type CallbackWithPromise } from '../../apis/callbacks.ts';
|
|
2
2
|
import { type FetchResponse } from '../../apis/consumer/fetch-v17.ts';
|
|
3
|
-
import {
|
|
3
|
+
import { type ConnectionPool } from '../../network/connection-pool.ts';
|
|
4
|
+
import { Base, type BaseEvents, kCreateConnectionPool } from '../base/base.ts';
|
|
4
5
|
import { MessagesStream } from './messages-stream.ts';
|
|
5
6
|
import { TopicsMap } from './topics-map.ts';
|
|
6
7
|
import { type CommitOptions, type ConsumeOptions, type ConsumerGroupJoinPayload, type ConsumerGroupLeavePayload, type ConsumerGroupRebalancePayload, type ConsumerHeartbeatErrorPayload, type ConsumerHeartbeatPayload, type ConsumerOptions, type FetchOptions, type GetLagOptions, type GroupAssignment, type GroupOptions, type ListCommitsOptions, type ListOffsetsOptions, type Offsets, type OffsetsWithTimestamps } from './types.ts';
|
|
@@ -28,6 +29,7 @@ export declare class Consumer<Key = Buffer, Value = Buffer, HeaderKey = Buffer,
|
|
|
28
29
|
get streamsCount(): number;
|
|
29
30
|
get lastHeartbeat(): Date | null;
|
|
30
31
|
get coordinatorId(): number | null;
|
|
32
|
+
get streamContext(): unknown;
|
|
31
33
|
close(force: boolean | CallbackWithPromise<void>, callback?: CallbackWithPromise<void>): void;
|
|
32
34
|
close(force?: boolean): Promise<void>;
|
|
33
35
|
isActive(): boolean;
|
|
@@ -49,6 +51,7 @@ export declare class Consumer<Key = Buffer, Value = Buffer, HeaderKey = Buffer,
|
|
|
49
51
|
stopLagMonitoring(): void;
|
|
50
52
|
findGroupCoordinator(callback: CallbackWithPromise<number>): void;
|
|
51
53
|
findGroupCoordinator(): Promise<number>;
|
|
54
|
+
[kCreateConnectionPool](context?: unknown): ConnectionPool;
|
|
52
55
|
joinGroup(options: GroupOptions, callback: CallbackWithPromise<string>): void;
|
|
53
56
|
joinGroup(options?: GroupOptions): Promise<string>;
|
|
54
57
|
leaveGroup(force?: boolean | CallbackWithPromise<void>, callback?: CallbackWithPromise<void>): void;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
1
2
|
import { createPromisifiedCallback, kCallbackPromise, runConcurrentCallbacks } from "../../apis/callbacks.js";
|
|
2
3
|
import { FetchIsolationLevels, FindCoordinatorKeyTypes } from "../../apis/enumerations.js";
|
|
3
4
|
import { consumerCommitsChannel, consumerConsumesChannel, consumerFetchesChannel, consumerGroupChannel, consumerHeartbeatChannel, consumerLagChannel, consumerOffsetsChannel, createDiagnosticContext } from "../../diagnostic.js";
|
|
@@ -8,7 +9,7 @@ import { IS_CONTROL } from "../../protocol/records.js";
|
|
|
8
9
|
import { Writer } from "../../protocol/writer.js";
|
|
9
10
|
import { kAutocommit, kRefreshOffsetsAndFetch } from "../../symbols.js";
|
|
10
11
|
import { emitExperimentalApiWarning } from "../../utils.js";
|
|
11
|
-
import { Base, kAfterCreate, kCheckNotClosed, kClosed, kConnections, kFormatValidationErrors, kGetApi, kGetBootstrapConnection, kGetConnection, kMetadata, kOptions, kPerformDeduplicated, kPerformWithRetry, kPrometheus, kValidateOptions } from "../base/base.js";
|
|
12
|
+
import { Base, kAfterCreate, kCheckNotClosed, kClosed, kConnections, kCreateConnectionPool, kFormatValidationErrors, kGetApi, kGetBootstrapConnection, kGetConnection, kMetadata, kOptions, kPerformDeduplicated, kPerformWithRetry, kPrometheus, kValidateOptions } from "../base/base.js";
|
|
12
13
|
import { ensureMetric } from "../metrics.js";
|
|
13
14
|
import { MessagesStream } from "./messages-stream.js";
|
|
14
15
|
import { commitOptionsValidator, consumeOptionsValidator, consumerOptionsValidator, defaultConsumerOptions, fetchOptionsValidator, getLagOptionsValidator, groupIdAndOptionsValidator, groupOptionsValidator, listCommitsOptionsValidator, listOffsetsOptionsValidator } from "./options.js";
|
|
@@ -35,6 +36,7 @@ export class Consumer extends Base {
|
|
|
35
36
|
#groupRemoteAssignor;
|
|
36
37
|
#streams;
|
|
37
38
|
#lagMonitoring;
|
|
39
|
+
#streamContext;
|
|
38
40
|
// Metrics
|
|
39
41
|
#metricActiveStreams;
|
|
40
42
|
#metricLags;
|
|
@@ -76,6 +78,7 @@ export class Consumer extends Base {
|
|
|
76
78
|
this.#memberEpoch = 0;
|
|
77
79
|
this.#useConsumerGroupProtocol = this[kOptions].groupProtocol === 'consumer';
|
|
78
80
|
this.#groupRemoteAssignor = this[kOptions].groupRemoteAssignor ?? null;
|
|
81
|
+
this.#streamContext = options.streamContext ?? options.context;
|
|
79
82
|
this.#validateGroupOptions(this[kOptions], groupIdAndOptionsValidator);
|
|
80
83
|
if (this[kPrometheus]) {
|
|
81
84
|
ensureMetric(this[kPrometheus], 'Gauge', 'kafka_consumers', 'Number of active Kafka consumers').inc();
|
|
@@ -94,6 +97,9 @@ export class Consumer extends Base {
|
|
|
94
97
|
get coordinatorId() {
|
|
95
98
|
return this.#coordinatorId;
|
|
96
99
|
}
|
|
100
|
+
get streamContext() {
|
|
101
|
+
return this.#streamContext;
|
|
102
|
+
}
|
|
97
103
|
close(force, callback) {
|
|
98
104
|
if (typeof force === 'function') {
|
|
99
105
|
callback = force;
|
|
@@ -169,6 +175,7 @@ export class Consumer extends Base {
|
|
|
169
175
|
options.highWaterMark ??= this[kOptions].highWaterMark;
|
|
170
176
|
options.registry ??= this[kOptions].registry;
|
|
171
177
|
options.beforeDeserialization ??= this[kOptions].beforeDeserialization;
|
|
178
|
+
options.context ??= this.#streamContext;
|
|
172
179
|
if (options.beforeDeserialization) {
|
|
173
180
|
emitExperimentalApiWarning('beforeDeserialization');
|
|
174
181
|
}
|
|
@@ -353,6 +360,9 @@ export class Consumer extends Base {
|
|
|
353
360
|
this.#findGroupCoordinator(callback);
|
|
354
361
|
return callback[kCallbackPromise];
|
|
355
362
|
}
|
|
363
|
+
[kCreateConnectionPool](context) {
|
|
364
|
+
return super[kCreateConnectionPool](context);
|
|
365
|
+
}
|
|
356
366
|
joinGroup(options, callback) {
|
|
357
367
|
if (!callback) {
|
|
358
368
|
callback = createPromisifiedCallback();
|
|
@@ -443,7 +453,21 @@ export class Consumer extends Base {
|
|
|
443
453
|
retryCallback(error);
|
|
444
454
|
return;
|
|
445
455
|
}
|
|
446
|
-
api(connection, options.maxWaitTime ?? this[kOptions].maxWaitTime, options.minBytes ?? this[kOptions].minBytes, options.maxBytes ?? this[kOptions].maxBytes, isolationLevel, 0, 0, options.topics, [], '',
|
|
456
|
+
api(connection, options.maxWaitTime ?? this[kOptions].maxWaitTime, options.minBytes ?? this[kOptions].minBytes, options.maxBytes ?? this[kOptions].maxBytes, isolationLevel, 0, 0, options.topics, [], '', (error, result) => {
|
|
457
|
+
if (error) {
|
|
458
|
+
const genericError = error;
|
|
459
|
+
if (genericError.findBy?.('apiId', 'FENCED_LEADER_EPOCH')) {
|
|
460
|
+
this.clearMetadata();
|
|
461
|
+
for (const topic of options.topics) {
|
|
462
|
+
for (const partition of topic.partitions) {
|
|
463
|
+
partition.currentLeaderEpoch = -1;
|
|
464
|
+
partition.lastFetchedEpoch = -1;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
retryCallback(error, result);
|
|
470
|
+
});
|
|
447
471
|
});
|
|
448
472
|
});
|
|
449
473
|
});
|
|
@@ -700,8 +724,9 @@ export class Consumer extends Base {
|
|
|
700
724
|
groupCallback(error);
|
|
701
725
|
return;
|
|
702
726
|
}
|
|
703
|
-
|
|
704
|
-
|
|
727
|
+
const memberId = this.#getConsumerGroupHeartbeatMemberId(api.version);
|
|
728
|
+
api(connection, this.groupId, memberId, this.#memberEpoch, this.groupInstanceId, null, // rackId
|
|
729
|
+
options.rebalanceTimeout, this.topics.current, null, this.#groupRemoteAssignor, this.#assignments, groupCallback);
|
|
705
730
|
});
|
|
706
731
|
}, (error, response) => {
|
|
707
732
|
if (this[kClosed]) {
|
|
@@ -812,6 +837,10 @@ export class Consumer extends Base {
|
|
|
812
837
|
}
|
|
813
838
|
#updateAssignments(newAssignments, callback) {
|
|
814
839
|
this[kMetadata]({ topics: this.topics.current }, (error, metadata) => {
|
|
840
|
+
if (!this.#membershipActive) {
|
|
841
|
+
callback(null);
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
815
844
|
if (error) {
|
|
816
845
|
callback(error);
|
|
817
846
|
return;
|
|
@@ -849,10 +878,12 @@ export class Consumer extends Base {
|
|
|
849
878
|
groupCallback(error);
|
|
850
879
|
return;
|
|
851
880
|
}
|
|
852
|
-
|
|
881
|
+
const memberId = this.#getConsumerGroupHeartbeatMemberId(api.version);
|
|
882
|
+
api(connection, this.groupId, memberId, -1, // memberEpoch = -1 signals leave
|
|
853
883
|
this.groupInstanceId, null, // rackId
|
|
854
884
|
0, // rebalanceTimeout
|
|
855
885
|
[], // subscribedTopicNames
|
|
886
|
+
null, // subscribedTopicRegex
|
|
856
887
|
this.#groupRemoteAssignor, [], // topicPartitions
|
|
857
888
|
groupCallback);
|
|
858
889
|
});
|
|
@@ -865,6 +896,16 @@ export class Consumer extends Base {
|
|
|
865
896
|
callback(null);
|
|
866
897
|
});
|
|
867
898
|
}
|
|
899
|
+
#getConsumerGroupHeartbeatMemberId(apiVersion) {
|
|
900
|
+
if (this.memberId) {
|
|
901
|
+
return this.memberId;
|
|
902
|
+
}
|
|
903
|
+
if (apiVersion >= 1) {
|
|
904
|
+
this.memberId = randomUUID();
|
|
905
|
+
return this.memberId;
|
|
906
|
+
}
|
|
907
|
+
return '';
|
|
908
|
+
}
|
|
868
909
|
#performConsume(options, trackTopics, callback) {
|
|
869
910
|
// Subscribe all topics
|
|
870
911
|
let joinNeeded = this.memberId === null;
|
|
@@ -15,6 +15,7 @@ export declare class MessagesStream<Key, Value, HeaderKey, HeaderValue> extends
|
|
|
15
15
|
constructor(consumer: Consumer<Key, Value, HeaderKey, HeaderValue>, options: ConsumeOptions<Key, Value, HeaderKey, HeaderValue>);
|
|
16
16
|
get consumer(): Consumer<Key, Value, HeaderKey, HeaderValue>;
|
|
17
17
|
get offsetsToFetch(): Map<string, bigint>;
|
|
18
|
+
get context(): unknown;
|
|
18
19
|
get offsetsToCommit(): Map<string, CommitOptionsPartition>;
|
|
19
20
|
get offsetsCommitted(): Map<string, bigint>;
|
|
20
21
|
get committedOffsets(): Map<string, bigint>;
|