@platformatic/kafka 1.25.0 → 1.26.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/dist/clients/base/base.d.ts +0 -1
- package/dist/clients/base/base.js +0 -1
- package/dist/clients/base/options.d.ts +4 -0
- package/dist/clients/base/options.js +1 -0
- package/dist/clients/consumer/consumer.d.ts +2 -3
- package/dist/clients/consumer/consumer.js +16 -39
- package/dist/clients/consumer/messages-stream.d.ts +3 -1
- package/dist/clients/consumer/messages-stream.js +57 -24
- package/dist/clients/consumer/options.d.ts +23 -0
- package/dist/clients/consumer/options.js +2 -0
- package/dist/clients/consumer/types.d.ts +4 -0
- package/dist/network/connection.d.ts +4 -1
- package/dist/network/connection.js +20 -12
- package/dist/protocol/records.d.ts +11 -0
- package/dist/typescript-4/dist/clients/base/base.d.ts +0 -1
- package/dist/typescript-4/dist/clients/base/options.d.ts +4 -0
- package/dist/typescript-4/dist/clients/consumer/consumer.d.ts +2 -3
- package/dist/typescript-4/dist/clients/consumer/messages-stream.d.ts +3 -1
- package/dist/typescript-4/dist/clients/consumer/options.d.ts +23 -0
- package/dist/typescript-4/dist/clients/consumer/types.d.ts +4 -0
- package/dist/typescript-4/dist/network/connection.d.ts +4 -1
- package/dist/typescript-4/dist/protocol/records.d.ts +11 -0
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -17,7 +17,6 @@ export declare const kGetConnection: unique symbol;
|
|
|
17
17
|
export declare const kGetBootstrapConnection: unique symbol;
|
|
18
18
|
export declare const kOptions: unique symbol;
|
|
19
19
|
export declare const kConnections: unique symbol;
|
|
20
|
-
export declare const kFetchConnections: unique symbol;
|
|
21
20
|
export declare const kCreateConnectionPool: unique symbol;
|
|
22
21
|
export declare const kClosed: unique symbol;
|
|
23
22
|
export declare const kListApis: unique symbol;
|
|
@@ -17,7 +17,6 @@ export const kGetConnection = Symbol('plt.kafka.base.getConnection');
|
|
|
17
17
|
export const kGetBootstrapConnection = Symbol('plt.kafka.base.getBootstrapConnection');
|
|
18
18
|
export const kOptions = Symbol('plt.kafka.base.options');
|
|
19
19
|
export const kConnections = Symbol('plt.kafka.base.connections');
|
|
20
|
-
export const kFetchConnections = Symbol('plt.kafka.base.fetchCnnections');
|
|
21
20
|
export const kCreateConnectionPool = Symbol('plt.kafka.base.createConnectionPool');
|
|
22
21
|
export const kClosed = Symbol('plt.kafka.base.closed');
|
|
23
22
|
export const kListApis = Symbol('plt.kafka.base.listApis');
|
|
@@ -33,6 +33,7 @@ export const baseOptionsSchema = {
|
|
|
33
33
|
maxInflights: { type: 'number', minimum: 0 },
|
|
34
34
|
handleBackPressure: { type: 'boolean', default: false },
|
|
35
35
|
tls: { type: 'object', additionalProperties: true }, // No validation as they come from Node.js
|
|
36
|
+
ssl: { type: 'object', additionalProperties: true }, // Alias for tls, no validation as they come from Node.js
|
|
36
37
|
tlsServerName: { oneOf: [{ type: 'boolean' }, { type: 'string' }] },
|
|
37
38
|
sasl: {
|
|
38
39
|
type: 'object',
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { type CallbackWithPromise } from '../../apis/callbacks.ts';
|
|
2
2
|
import { type FetchResponse } from '../../apis/consumer/fetch-v17.ts';
|
|
3
|
-
import { type
|
|
4
|
-
import { Base, type BaseEvents, kFetchConnections } from '../base/base.ts';
|
|
3
|
+
import { Base, type BaseEvents } from '../base/base.ts';
|
|
5
4
|
import { MessagesStream } from './messages-stream.ts';
|
|
6
5
|
import { TopicsMap } from './topics-map.ts';
|
|
7
6
|
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';
|
|
@@ -20,11 +19,11 @@ export interface ConsumerEvents extends BaseEvents {
|
|
|
20
19
|
export declare class Consumer<Key = Buffer, Value = Buffer, HeaderKey = Buffer, HeaderValue = Buffer> extends Base<ConsumerOptions<Key, Value, HeaderKey, HeaderValue>, ConsumerEvents> {
|
|
21
20
|
#private;
|
|
22
21
|
groupId: string;
|
|
22
|
+
groupInstanceId: string | null;
|
|
23
23
|
generationId: number;
|
|
24
24
|
memberId: string | null;
|
|
25
25
|
topics: TopicsMap;
|
|
26
26
|
assignments: GroupAssignment[] | null;
|
|
27
|
-
[kFetchConnections]: ConnectionPool;
|
|
28
27
|
constructor(options: ConsumerOptions<Key, Value, HeaderKey, HeaderValue>);
|
|
29
28
|
get streamsCount(): number;
|
|
30
29
|
get lastHeartbeat(): Date | null;
|
|
@@ -7,7 +7,7 @@ import { Reader } from "../../protocol/reader.js";
|
|
|
7
7
|
import { IS_CONTROL } from "../../protocol/records.js";
|
|
8
8
|
import { Writer } from "../../protocol/writer.js";
|
|
9
9
|
import { kAutocommit, kRefreshOffsetsAndFetch } from "../../symbols.js";
|
|
10
|
-
import { Base, kAfterCreate, kCheckNotClosed, kClosed,
|
|
10
|
+
import { Base, kAfterCreate, kCheckNotClosed, kClosed, kConnections, kFormatValidationErrors, kGetApi, kGetBootstrapConnection, kGetConnection, kMetadata, kOptions, kPerformDeduplicated, kPerformWithRetry, kPrometheus, kValidateOptions } from "../base/base.js";
|
|
11
11
|
import { ensureMetric } from "../metrics.js";
|
|
12
12
|
import { MessagesStream } from "./messages-stream.js";
|
|
13
13
|
import { commitOptionsValidator, consumeOptionsValidator, consumerOptionsValidator, defaultConsumerOptions, fetchOptionsValidator, getLagOptionsValidator, groupIdAndOptionsValidator, groupOptionsValidator, listCommitsOptionsValidator, listOffsetsOptionsValidator } from "./options.js";
|
|
@@ -15,6 +15,7 @@ import { roundRobinAssigner } from "./partitions-assigners.js";
|
|
|
15
15
|
import { TopicsMap } from "./topics-map.js";
|
|
16
16
|
export class Consumer extends Base {
|
|
17
17
|
groupId;
|
|
18
|
+
groupInstanceId;
|
|
18
19
|
generationId;
|
|
19
20
|
memberId;
|
|
20
21
|
topics;
|
|
@@ -33,21 +34,6 @@ export class Consumer extends Base {
|
|
|
33
34
|
#groupRemoteAssignor;
|
|
34
35
|
#streams;
|
|
35
36
|
#lagMonitoring;
|
|
36
|
-
/*
|
|
37
|
-
The following requests are blocking in Kafka:
|
|
38
|
-
|
|
39
|
-
FetchRequest (soprattutto con maxWaitMs)
|
|
40
|
-
JoinGroupRequest
|
|
41
|
-
SyncGroupRequest
|
|
42
|
-
OffsetCommitRequest
|
|
43
|
-
ProduceRequest
|
|
44
|
-
ListOffsetsRequest
|
|
45
|
-
ListGroupsRequest
|
|
46
|
-
DescribeGroupsRequest
|
|
47
|
-
|
|
48
|
-
In order to avoid consumer group problems, we separate FetchRequest only on a separate connection.
|
|
49
|
-
*/
|
|
50
|
-
[kFetchConnections];
|
|
51
37
|
// Metrics
|
|
52
38
|
#metricActiveStreams;
|
|
53
39
|
#metricLags;
|
|
@@ -55,6 +41,7 @@ export class Consumer extends Base {
|
|
|
55
41
|
super({ ...defaultConsumerOptions, ...options });
|
|
56
42
|
this[kValidateOptions](options, consumerOptionsValidator, '/options');
|
|
57
43
|
this.groupId = options.groupId;
|
|
44
|
+
this.groupInstanceId = options.groupInstanceId ?? null;
|
|
58
45
|
this.generationId = 0;
|
|
59
46
|
this.memberId = null;
|
|
60
47
|
this.topics = new TopicsMap();
|
|
@@ -74,8 +61,6 @@ export class Consumer extends Base {
|
|
|
74
61
|
this.#useConsumerGroupProtocol = this[kOptions].groupProtocol === 'consumer';
|
|
75
62
|
this.#groupRemoteAssignor = this[kOptions].groupRemoteAssignor ?? null;
|
|
76
63
|
this.#validateGroupOptions(this[kOptions], groupIdAndOptionsValidator);
|
|
77
|
-
// Initialize connection pool
|
|
78
|
-
this[kFetchConnections] = this[kCreateConnectionPool]();
|
|
79
64
|
if (this[kPrometheus]) {
|
|
80
65
|
ensureMetric(this[kPrometheus], 'Gauge', 'kafka_consumers', 'Number of active Kafka consumers').inc();
|
|
81
66
|
this.#metricActiveStreams = ensureMetric(this[kPrometheus], 'Gauge', 'kafka_consumers_streams', 'Number of active Kafka consumers streams');
|
|
@@ -125,24 +110,17 @@ export class Consumer extends Base {
|
|
|
125
110
|
callback(error);
|
|
126
111
|
return;
|
|
127
112
|
}
|
|
128
|
-
|
|
113
|
+
super.close(error => {
|
|
129
114
|
if (error) {
|
|
130
115
|
this[kClosed] = false;
|
|
131
116
|
callback(error);
|
|
132
117
|
return;
|
|
133
118
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
this.topics.clear();
|
|
141
|
-
if (this[kPrometheus]) {
|
|
142
|
-
ensureMetric(this[kPrometheus], 'Gauge', 'kafka_consumers', 'Number of active Kafka consumers').dec();
|
|
143
|
-
}
|
|
144
|
-
callback(null);
|
|
145
|
-
});
|
|
119
|
+
this.topics.clear();
|
|
120
|
+
if (this[kPrometheus]) {
|
|
121
|
+
ensureMetric(this[kPrometheus], 'Gauge', 'kafka_consumers', 'Number of active Kafka consumers').dec();
|
|
122
|
+
}
|
|
123
|
+
callback(null);
|
|
146
124
|
});
|
|
147
125
|
});
|
|
148
126
|
return callback[kCallbackPromise];
|
|
@@ -410,7 +388,8 @@ export class Consumer extends Base {
|
|
|
410
388
|
retryCallback(new UserError(`Cannot find broker with node id ${options.node}`));
|
|
411
389
|
return;
|
|
412
390
|
}
|
|
413
|
-
|
|
391
|
+
const pool = options.connectionPool ?? this[kConnections];
|
|
392
|
+
pool.get(broker, (error, connection) => {
|
|
414
393
|
if (error) {
|
|
415
394
|
// When a connection was not available (either interrupted or not available) we
|
|
416
395
|
// reset the leader epoch in the options so that when connection is re-established again we can continue
|
|
@@ -638,7 +617,7 @@ export class Consumer extends Base {
|
|
|
638
617
|
groupCallback(error);
|
|
639
618
|
return;
|
|
640
619
|
}
|
|
641
|
-
api(connection, this.groupId, this.generationId, this.memberId,
|
|
620
|
+
api(connection, this.groupId, this.generationId, this.memberId, this.groupInstanceId, groupCallback);
|
|
642
621
|
});
|
|
643
622
|
}, error => {
|
|
644
623
|
// The heartbeat has been aborted elsewhere, ignore the response
|
|
@@ -685,8 +664,7 @@ export class Consumer extends Base {
|
|
|
685
664
|
groupCallback(error);
|
|
686
665
|
return;
|
|
687
666
|
}
|
|
688
|
-
api(connection, this.groupId, this.memberId || '', this.#memberEpoch, null, //
|
|
689
|
-
null, // rackId
|
|
667
|
+
api(connection, this.groupId, this.memberId || '', this.#memberEpoch, this.groupInstanceId, null, // rackId
|
|
690
668
|
options.rebalanceTimeout, this.topics.current, this.#groupRemoteAssignor, this.#assignments, groupCallback);
|
|
691
669
|
});
|
|
692
670
|
}, (error, response) => {
|
|
@@ -836,8 +814,7 @@ export class Consumer extends Base {
|
|
|
836
814
|
return;
|
|
837
815
|
}
|
|
838
816
|
api(connection, this.groupId, this.memberId, -1, // memberEpoch = -1 signals leave
|
|
839
|
-
null, //
|
|
840
|
-
null, // rackId
|
|
817
|
+
this.groupInstanceId, null, // rackId
|
|
841
818
|
0, // rebalanceTimeout
|
|
842
819
|
[], // subscribedTopicNames
|
|
843
820
|
this.#groupRemoteAssignor, [], // topicPartitions
|
|
@@ -941,7 +918,7 @@ export class Consumer extends Base {
|
|
|
941
918
|
groupCallback(error);
|
|
942
919
|
return;
|
|
943
920
|
}
|
|
944
|
-
api(connection, this.groupId, options.sessionTimeout, options.rebalanceTimeout, this.memberId ?? '',
|
|
921
|
+
api(connection, this.groupId, options.sessionTimeout, options.rebalanceTimeout, this.memberId ?? '', this.groupInstanceId, 'consumer', protocols, '', groupCallback);
|
|
945
922
|
});
|
|
946
923
|
}, (error, response) => {
|
|
947
924
|
if (!this.#membershipActive) {
|
|
@@ -1091,7 +1068,7 @@ export class Consumer extends Base {
|
|
|
1091
1068
|
groupCallback(error);
|
|
1092
1069
|
return;
|
|
1093
1070
|
}
|
|
1094
|
-
api(connection, this.groupId, this.generationId, this.memberId,
|
|
1071
|
+
api(connection, this.groupId, this.generationId, this.memberId, this.groupInstanceId, 'consumer', this.#protocol, assignments, groupCallback);
|
|
1095
1072
|
});
|
|
1096
1073
|
}, (error, response) => {
|
|
1097
1074
|
if (!this.#membershipActive) {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Readable } from 'node:stream';
|
|
2
2
|
import { type CallbackWithPromise } from '../../apis/callbacks.ts';
|
|
3
|
+
import { type ConnectionPool } from '../../network/connection-pool.ts';
|
|
3
4
|
import { type Message } from '../../protocol/records.ts';
|
|
4
5
|
import { kAutocommit, kInstance, kRefreshOffsetsAndFetch } from '../../symbols.ts';
|
|
5
|
-
import { kInspect } from '../base/base.ts';
|
|
6
|
+
import { kConnections, kInspect } from '../base/base.ts';
|
|
6
7
|
import { type Consumer } from './consumer.ts';
|
|
7
8
|
import { type CommitOptionsPartition, type ConsumeOptions } from './types.ts';
|
|
8
9
|
export declare function noopDeserializer(data?: Buffer): Buffer | undefined;
|
|
@@ -10,6 +11,7 @@ export declare function defaultCorruptedMessageHandler(): boolean;
|
|
|
10
11
|
export declare class MessagesStream<Key, Value, HeaderKey, HeaderValue> extends Readable {
|
|
11
12
|
#private;
|
|
12
13
|
[kInstance]: number;
|
|
14
|
+
[kConnections]: ConnectionPool;
|
|
13
15
|
constructor(consumer: Consumer<Key, Value, HeaderKey, HeaderValue>, options: ConsumeOptions<Key, Value, HeaderKey, HeaderValue>);
|
|
14
16
|
get consumer(): Consumer<Key, Value, HeaderKey, HeaderValue>;
|
|
15
17
|
get offsetsToFetch(): Map<string, bigint>;
|
|
@@ -5,7 +5,7 @@ import { consumerReceivesChannel, createDiagnosticContext, notifyCreation } from
|
|
|
5
5
|
import { UserError } from "../../errors.js";
|
|
6
6
|
import { IS_CONTROL } from "../../protocol/records.js";
|
|
7
7
|
import { kAutocommit, kInstance, kRefreshOffsetsAndFetch } from "../../symbols.js";
|
|
8
|
-
import { kInspect, kPrometheus } from "../base/base.js";
|
|
8
|
+
import { kConnections, kCreateConnectionPool, kInspect, kPrometheus } from "../base/base.js";
|
|
9
9
|
import { ensureMetric } from "../metrics.js";
|
|
10
10
|
import { defaultConsumerOptions } from "./options.js";
|
|
11
11
|
import { MessagesStreamFallbackModes, MessagesStreamModes } from "./types.js";
|
|
@@ -18,6 +18,18 @@ export function noopDeserializer(data) {
|
|
|
18
18
|
export function defaultCorruptedMessageHandler() {
|
|
19
19
|
return true;
|
|
20
20
|
}
|
|
21
|
+
function messageToJSON() {
|
|
22
|
+
return {
|
|
23
|
+
key: this.key,
|
|
24
|
+
value: this.value,
|
|
25
|
+
headers: Array.from(this.headers.entries()),
|
|
26
|
+
topic: this.topic,
|
|
27
|
+
partition: this.partition,
|
|
28
|
+
timestamp: this.timestamp.toString(),
|
|
29
|
+
offset: this.offset.toString(),
|
|
30
|
+
metadata: this.metadata
|
|
31
|
+
};
|
|
32
|
+
}
|
|
21
33
|
let currentInstance = 0;
|
|
22
34
|
export class MessagesStream extends Readable {
|
|
23
35
|
#consumer;
|
|
@@ -40,11 +52,27 @@ export class MessagesStream extends Readable {
|
|
|
40
52
|
#autocommitEnabled;
|
|
41
53
|
#autocommitInterval;
|
|
42
54
|
#autocommitInflight;
|
|
43
|
-
#
|
|
55
|
+
#closed;
|
|
44
56
|
#closeCallbacks;
|
|
45
57
|
#metricsConsumedMessages;
|
|
46
58
|
#corruptedMessageHandler;
|
|
47
59
|
[kInstance];
|
|
60
|
+
/*
|
|
61
|
+
The following requests are blocking in Kafka:
|
|
62
|
+
|
|
63
|
+
FetchRequest (soprattutto con maxWaitMs)
|
|
64
|
+
JoinGroupRequest
|
|
65
|
+
SyncGroupRequest
|
|
66
|
+
OffsetCommitRequest
|
|
67
|
+
ProduceRequest
|
|
68
|
+
ListOffsetsRequest
|
|
69
|
+
ListGroupsRequest
|
|
70
|
+
DescribeGroupsRequest
|
|
71
|
+
|
|
72
|
+
In order to avoid consumer group problems, we separate FetchRequest only on a separate connection.
|
|
73
|
+
Also, to avoid head-of-line blocking between streams, we use a pool of connections for each stream.
|
|
74
|
+
*/
|
|
75
|
+
[kConnections];
|
|
48
76
|
constructor(consumer, options) {
|
|
49
77
|
const { autocommit, mode, fallbackMode, maxFetches, offsets, deserializers, onCorruptedMessage,
|
|
50
78
|
// The options below are only destructured to avoid being part of structuredClone below
|
|
@@ -61,6 +89,7 @@ export class MessagesStream extends Readable {
|
|
|
61
89
|
highWaterMark: maxFetches ?? options.highWaterMark ?? defaultConsumerOptions.highWaterMark
|
|
62
90
|
});
|
|
63
91
|
this[kInstance] = currentInstance++;
|
|
92
|
+
this[kConnections] = consumer[kCreateConnectionPool]();
|
|
64
93
|
this.#consumer = consumer;
|
|
65
94
|
this.#mode = mode ?? MessagesStreamModes.LATEST;
|
|
66
95
|
this.#fallbackMode = fallbackMode ?? MessagesStreamFallbackModes.LATEST;
|
|
@@ -78,7 +107,7 @@ export class MessagesStream extends Readable {
|
|
|
78
107
|
this.#headerValueDeserializer = deserializers?.headerValue ?? noopDeserializer;
|
|
79
108
|
this.#autocommitEnabled = !!options.autocommit;
|
|
80
109
|
this.#autocommitInflight = false;
|
|
81
|
-
this.#
|
|
110
|
+
this.#closed = false;
|
|
82
111
|
this.#closeCallbacks = [];
|
|
83
112
|
this.#corruptedMessageHandler = onCorruptedMessage ?? defaultCorruptedMessageHandler;
|
|
84
113
|
// Restore offsets
|
|
@@ -150,11 +179,11 @@ export class MessagesStream extends Readable {
|
|
|
150
179
|
return callback[kCallbackPromise];
|
|
151
180
|
}
|
|
152
181
|
this.#closeCallbacks.push(callback);
|
|
153
|
-
if (this.#
|
|
154
|
-
this.#
|
|
182
|
+
if (this.#closed) {
|
|
183
|
+
this.#afterClose(null);
|
|
155
184
|
return callback[kCallbackPromise];
|
|
156
185
|
}
|
|
157
|
-
this.#
|
|
186
|
+
this.#closed = true;
|
|
158
187
|
this.push(null);
|
|
159
188
|
if (this.#autocommitInterval) {
|
|
160
189
|
clearInterval(this.#autocommitInterval);
|
|
@@ -166,32 +195,33 @@ export class MessagesStream extends Readable {
|
|
|
166
195
|
}
|
|
167
196
|
/* c8 ignore next 3 - Hard to test */
|
|
168
197
|
this.once('error', error => {
|
|
169
|
-
|
|
198
|
+
this.#afterClose(error);
|
|
170
199
|
});
|
|
171
200
|
this.once('close', () => {
|
|
172
201
|
// We have offsets that were enqueued to be committed. Perform the operation
|
|
202
|
+
/* c8 ignore next 3 - Hard to test */
|
|
173
203
|
if (this.#offsetsToCommit.size > 0) {
|
|
174
204
|
this[kAutocommit]();
|
|
175
205
|
}
|
|
176
206
|
// We have offsets that are being committed. These are awaited despite of the force parameters
|
|
177
207
|
if (this.#autocommitInflight) {
|
|
178
208
|
this.once('autocommit', error => {
|
|
179
|
-
this.#
|
|
209
|
+
this.#afterClose(error);
|
|
180
210
|
});
|
|
181
211
|
return;
|
|
182
212
|
}
|
|
183
|
-
this.#
|
|
213
|
+
this.#afterClose(null);
|
|
184
214
|
});
|
|
185
215
|
return callback[kCallbackPromise];
|
|
186
216
|
}
|
|
187
217
|
isActive() {
|
|
188
|
-
if (this.#
|
|
218
|
+
if (this.#closed || this.closed || this.destroyed) {
|
|
189
219
|
return false;
|
|
190
220
|
}
|
|
191
221
|
return this.#consumer.isActive();
|
|
192
222
|
}
|
|
193
223
|
isConnected() {
|
|
194
|
-
if (this.#
|
|
224
|
+
if (this.#closed || this.closed || this.destroyed) {
|
|
195
225
|
return false;
|
|
196
226
|
}
|
|
197
227
|
return this.#consumer.isConnected();
|
|
@@ -243,7 +273,7 @@ export class MessagesStream extends Readable {
|
|
|
243
273
|
}
|
|
244
274
|
#fetch() {
|
|
245
275
|
/* c8 ignore next 4 - Hard to test */
|
|
246
|
-
if (this.#
|
|
276
|
+
if (this.#closed || this.closed || this.destroyed) {
|
|
247
277
|
this.push(null);
|
|
248
278
|
return;
|
|
249
279
|
}
|
|
@@ -256,7 +286,7 @@ export class MessagesStream extends Readable {
|
|
|
256
286
|
this.emit('fetch');
|
|
257
287
|
// The stream has been closed, ignore any error
|
|
258
288
|
/* c8 ignore next 4 - Hard to test */
|
|
259
|
-
if (this.#
|
|
289
|
+
if (this.#closed || this.closed || this.destroyed) {
|
|
260
290
|
this.push(null);
|
|
261
291
|
return;
|
|
262
292
|
}
|
|
@@ -264,7 +294,7 @@ export class MessagesStream extends Readable {
|
|
|
264
294
|
return;
|
|
265
295
|
}
|
|
266
296
|
/* c8 ignore next 5 - Hard to test */
|
|
267
|
-
if (this.#
|
|
297
|
+
if (this.#closed || this.closed || this.destroyed) {
|
|
268
298
|
this.emit('fetch');
|
|
269
299
|
this.push(null);
|
|
270
300
|
return;
|
|
@@ -317,14 +347,14 @@ export class MessagesStream extends Readable {
|
|
|
317
347
|
if (error) {
|
|
318
348
|
// The stream has been closed, ignore the error
|
|
319
349
|
/* c8 ignore next 4 - Hard to test */
|
|
320
|
-
if (this.#
|
|
350
|
+
if (this.#closed || this.closed || this.destroyed) {
|
|
321
351
|
this.push(null);
|
|
322
352
|
return;
|
|
323
353
|
}
|
|
324
354
|
this.destroy(error);
|
|
325
355
|
return;
|
|
326
356
|
}
|
|
327
|
-
if (this.#
|
|
357
|
+
if (this.#closed || this.closed || this.destroyed) {
|
|
328
358
|
// When it's the last inflight, we finally close the stream.
|
|
329
359
|
// This is done to avoid the user exiting from consmuming metrics like for-await and still see the process up.
|
|
330
360
|
if (this.#inflightNodes.size === 0) {
|
|
@@ -421,7 +451,8 @@ export class MessagesStream extends Readable {
|
|
|
421
451
|
timestamp: firstTimestamp + record.timestampDelta,
|
|
422
452
|
offset,
|
|
423
453
|
commit,
|
|
424
|
-
metadata: messageMetadata
|
|
454
|
+
metadata: messageMetadata,
|
|
455
|
+
toJSON: messageToJSON
|
|
425
456
|
};
|
|
426
457
|
diagnosticContext.result = message;
|
|
427
458
|
consumerReceivesChannel.asyncStart.publish(diagnosticContext);
|
|
@@ -512,7 +543,7 @@ export class MessagesStream extends Readable {
|
|
|
512
543
|
}, (error, offsets) => {
|
|
513
544
|
if (error) {
|
|
514
545
|
/* c8 ignore next 4 - Hard to test */
|
|
515
|
-
if (this.#
|
|
546
|
+
if (this.#closed || this.closed || this.destroyed) {
|
|
516
547
|
callback(null);
|
|
517
548
|
return;
|
|
518
549
|
}
|
|
@@ -539,7 +570,7 @@ export class MessagesStream extends Readable {
|
|
|
539
570
|
this.#consumer.listCommittedOffsets({ topics }, (error, commits) => {
|
|
540
571
|
if (error) {
|
|
541
572
|
/* c8 ignore next 4 - Hard to test */
|
|
542
|
-
if (this.#
|
|
573
|
+
if (this.#closed || this.closed || this.destroyed) {
|
|
543
574
|
callback(null);
|
|
544
575
|
return;
|
|
545
576
|
}
|
|
@@ -594,11 +625,13 @@ export class MessagesStream extends Readable {
|
|
|
594
625
|
#assignmentsForTopic(topic) {
|
|
595
626
|
return this.#consumer.assignments?.find(assignment => assignment.topic === topic);
|
|
596
627
|
}
|
|
597
|
-
#
|
|
598
|
-
|
|
599
|
-
callback
|
|
600
|
-
|
|
601
|
-
|
|
628
|
+
#afterClose(error) {
|
|
629
|
+
this[kConnections].close(closeError => {
|
|
630
|
+
for (const callback of this.#closeCallbacks) {
|
|
631
|
+
callback(error ?? closeError);
|
|
632
|
+
}
|
|
633
|
+
this.#closeCallbacks = [];
|
|
634
|
+
});
|
|
602
635
|
}
|
|
603
636
|
/* c8 ignore next 3 - This is a private API used to debug during development */
|
|
604
637
|
[kInspect](...args) {
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export declare const groupOptionsProperties: {
|
|
2
|
+
groupInstanceId: {
|
|
3
|
+
type: string;
|
|
4
|
+
pattern: string;
|
|
5
|
+
};
|
|
2
6
|
sessionTimeout: {
|
|
3
7
|
type: string;
|
|
4
8
|
minimum: number;
|
|
@@ -127,6 +131,10 @@ export declare const consumeOptionsProperties: {
|
|
|
127
131
|
export declare const groupOptionsSchema: {
|
|
128
132
|
type: string;
|
|
129
133
|
properties: {
|
|
134
|
+
groupInstanceId: {
|
|
135
|
+
type: string;
|
|
136
|
+
pattern: string;
|
|
137
|
+
};
|
|
130
138
|
sessionTimeout: {
|
|
131
139
|
type: string;
|
|
132
140
|
minimum: number;
|
|
@@ -233,6 +241,10 @@ export declare const consumeOptionsSchema: {
|
|
|
233
241
|
type: string;
|
|
234
242
|
minimum: number;
|
|
235
243
|
};
|
|
244
|
+
groupInstanceId: {
|
|
245
|
+
type: string;
|
|
246
|
+
pattern: string;
|
|
247
|
+
};
|
|
236
248
|
sessionTimeout: {
|
|
237
249
|
type: string;
|
|
238
250
|
minimum: number;
|
|
@@ -384,6 +396,10 @@ export declare const consumerOptionsSchema: {
|
|
|
384
396
|
type: string;
|
|
385
397
|
minimum: number;
|
|
386
398
|
};
|
|
399
|
+
groupInstanceId: {
|
|
400
|
+
type: string;
|
|
401
|
+
pattern: string;
|
|
402
|
+
};
|
|
387
403
|
sessionTimeout: {
|
|
388
404
|
type: string;
|
|
389
405
|
minimum: number;
|
|
@@ -495,6 +511,10 @@ export declare const fetchOptionsSchema: {
|
|
|
495
511
|
type: string;
|
|
496
512
|
minimum: number;
|
|
497
513
|
};
|
|
514
|
+
groupInstanceId: {
|
|
515
|
+
type: string;
|
|
516
|
+
pattern: string;
|
|
517
|
+
};
|
|
498
518
|
sessionTimeout: {
|
|
499
519
|
type: string;
|
|
500
520
|
minimum: number;
|
|
@@ -588,6 +608,9 @@ export declare const fetchOptionsSchema: {
|
|
|
588
608
|
required: string[];
|
|
589
609
|
};
|
|
590
610
|
};
|
|
611
|
+
connectionPool: {
|
|
612
|
+
type: string;
|
|
613
|
+
};
|
|
591
614
|
};
|
|
592
615
|
required: string[];
|
|
593
616
|
additionalProperties: boolean;
|
|
@@ -4,6 +4,7 @@ import { idProperty, topicWithPartitionAndOffsetProperties } from "../base/optio
|
|
|
4
4
|
import { serdeProperties } from "../serde.js";
|
|
5
5
|
import { allowedMessagesStreamFallbackModes, allowedMessagesStreamModes } from "./types.js";
|
|
6
6
|
export const groupOptionsProperties = {
|
|
7
|
+
groupInstanceId: { type: 'string', pattern: '^\\S+$' },
|
|
7
8
|
sessionTimeout: { type: 'number', minimum: 0 },
|
|
8
9
|
rebalanceTimeout: { type: 'number', minimum: 0 },
|
|
9
10
|
heartbeatInterval: { type: 'number', minimum: 0 },
|
|
@@ -128,6 +129,7 @@ export const fetchOptionsSchema = {
|
|
|
128
129
|
required: ['topicId', 'partitions']
|
|
129
130
|
}
|
|
130
131
|
},
|
|
132
|
+
connectionPool: { type: 'object' },
|
|
131
133
|
...groupOptionsProperties,
|
|
132
134
|
...consumeOptionsProperties
|
|
133
135
|
},
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type FetchRequestTopic } from '../../apis/consumer/fetch-v17.ts';
|
|
2
2
|
import { type GroupProtocols } from '../../apis/enumerations.ts';
|
|
3
|
+
import { type ConnectionPool } from '../../network/connection-pool.ts';
|
|
3
4
|
import { type KafkaRecord, type Message } from '../../protocol/records.ts';
|
|
4
5
|
import { type BaseOptions, type ClusterMetadata, type TopicWithPartitionAndOffset } from '../base/types.ts';
|
|
5
6
|
import { type Deserializers } from '../serde.ts';
|
|
@@ -46,6 +47,7 @@ export type MessagesStreamFallbackMode = keyof typeof MessagesStreamFallbackMode
|
|
|
46
47
|
export type MessagesStreamFallbackModeValue = (typeof MessagesStreamFallbackModes)[keyof typeof MessagesStreamFallbackModes];
|
|
47
48
|
export interface GroupOptions {
|
|
48
49
|
groupProtocol?: typeof GroupProtocols.CLASSIC;
|
|
50
|
+
groupInstanceId?: string;
|
|
49
51
|
sessionTimeout?: number;
|
|
50
52
|
rebalanceTimeout?: number;
|
|
51
53
|
heartbeatInterval?: number;
|
|
@@ -54,6 +56,7 @@ export interface GroupOptions {
|
|
|
54
56
|
}
|
|
55
57
|
export interface ConsumerGroupOptions {
|
|
56
58
|
groupProtocol: typeof GroupProtocols.CONSUMER;
|
|
59
|
+
groupInstanceId?: string;
|
|
57
60
|
groupRemoteAssignor?: string;
|
|
58
61
|
rebalanceTimeout?: number;
|
|
59
62
|
}
|
|
@@ -81,6 +84,7 @@ export type ConsumerOptions<Key, Value, HeaderKey, HeaderValue> = BaseOptions &
|
|
|
81
84
|
export type FetchOptions<Key, Value, HeaderKey, HeaderValue> = Pick<ConsumeBaseOptions<Key, Value, HeaderKey, HeaderValue>, 'minBytes' | 'maxBytes' | 'maxWaitTime' | 'isolationLevel'> & {
|
|
82
85
|
node: number;
|
|
83
86
|
topics: FetchRequestTopic[];
|
|
87
|
+
connectionPool?: ConnectionPool;
|
|
84
88
|
};
|
|
85
89
|
export interface CommitOptionsPartition extends TopicWithPartitionAndOffset {
|
|
86
90
|
leaderEpoch: number;
|
|
@@ -4,8 +4,8 @@ import { type CallbackWithPromise } from '../apis/callbacks.ts';
|
|
|
4
4
|
import { type Callback, type ResponseParser } from '../apis/definitions.ts';
|
|
5
5
|
import { type SASLMechanismValue } from '../apis/enumerations.ts';
|
|
6
6
|
import { type SaslAuthenticateResponse, type SASLAuthenticationAPI } from '../apis/security/sasl-authenticate-v2.ts';
|
|
7
|
-
import { TypedEventEmitter, type TypedEvents } from '../events.ts';
|
|
8
7
|
import { TimeoutError } from '../errors.ts';
|
|
8
|
+
import { TypedEventEmitter, type TypedEvents } from '../events.ts';
|
|
9
9
|
import { Writer } from '../protocol/writer.ts';
|
|
10
10
|
export interface ConnectionEvents extends TypedEvents {
|
|
11
11
|
connecting: () => void;
|
|
@@ -40,6 +40,7 @@ export interface ConnectionOptions {
|
|
|
40
40
|
requestTimeout?: number;
|
|
41
41
|
maxInflights?: number;
|
|
42
42
|
tls?: TLSConnectionOptions;
|
|
43
|
+
ssl?: TLSConnectionOptions;
|
|
43
44
|
tlsServerName?: string | boolean;
|
|
44
45
|
sasl?: SASLOptions;
|
|
45
46
|
ownerId?: number;
|
|
@@ -62,6 +63,7 @@ export declare const ConnectionStatuses: {
|
|
|
62
63
|
readonly NONE: "none";
|
|
63
64
|
readonly CONNECTING: "connecting";
|
|
64
65
|
readonly AUTHENTICATING: "authenticating";
|
|
66
|
+
readonly REAUTHENTICATING: "reauthenticating";
|
|
65
67
|
readonly CONNECTED: "connected";
|
|
66
68
|
readonly CLOSED: "closed";
|
|
67
69
|
readonly CLOSING: "closing";
|
|
@@ -89,4 +91,5 @@ export declare class Connection extends TypedEventEmitter<ConnectionEvents> {
|
|
|
89
91
|
close(callback: CallbackWithPromise<void>): void;
|
|
90
92
|
close(): Promise<void>;
|
|
91
93
|
send<ReturnType>(apiKey: number, apiVersion: number, createPayload: () => Writer, responseParser: ResponseParser<ReturnType>, hasRequestHeaderTaggedFields: boolean, hasResponseHeaderTaggedFields: boolean, callback: Callback<ReturnType>): void;
|
|
94
|
+
reauthenticate(): void;
|
|
92
95
|
}
|
|
@@ -5,8 +5,8 @@ import { createPromisifiedCallback, kCallbackPromise } from "../apis/callbacks.j
|
|
|
5
5
|
import { allowedSASLMechanisms, SASLMechanisms } from "../apis/enumerations.js";
|
|
6
6
|
import { saslAuthenticateV2, saslHandshakeV1 } from "../apis/index.js";
|
|
7
7
|
import { connectionsApiChannel, connectionsConnectsChannel, createDiagnosticContext, notifyCreation } from "../diagnostic.js";
|
|
8
|
-
import { TypedEventEmitter } from "../events.js";
|
|
9
8
|
import { AuthenticationError, NetworkError, TimeoutError, UnexpectedCorrelationIdError, UserError } from "../errors.js";
|
|
9
|
+
import { TypedEventEmitter } from "../events.js";
|
|
10
10
|
import { protocolAPIsById } from "../protocol/apis.js";
|
|
11
11
|
import { EMPTY_OR_SINGLE_COMPACT_LENGTH_SIZE, INT32_SIZE } from "../protocol/definitions.js";
|
|
12
12
|
import { DynamicBuffer } from "../protocol/dynamic-buffer.js";
|
|
@@ -19,6 +19,7 @@ export const ConnectionStatuses = {
|
|
|
19
19
|
NONE: 'none',
|
|
20
20
|
CONNECTING: 'connecting',
|
|
21
21
|
AUTHENTICATING: 'authenticating',
|
|
22
|
+
REAUTHENTICATING: 'reauthenticating',
|
|
22
23
|
CONNECTED: 'connected',
|
|
23
24
|
CLOSED: 'closed',
|
|
24
25
|
CLOSING: 'closing',
|
|
@@ -55,6 +56,7 @@ export class Connection extends TypedEventEmitter {
|
|
|
55
56
|
this.setMaxListeners(0);
|
|
56
57
|
this.#instanceId = currentInstance++;
|
|
57
58
|
this.#options = Object.assign({}, defaultOptions, options);
|
|
59
|
+
this.#options.tls ??= this.#options.ssl;
|
|
58
60
|
this.#status = ConnectionStatuses.NONE;
|
|
59
61
|
this.#clientId = clientId;
|
|
60
62
|
this.#ownerId = options.ownerId;
|
|
@@ -261,6 +263,17 @@ export class Connection extends TypedEventEmitter {
|
|
|
261
263
|
return this.#sendRequest(request);
|
|
262
264
|
}, this.#onResponse.bind(this, request, callback));
|
|
263
265
|
}
|
|
266
|
+
reauthenticate() {
|
|
267
|
+
if (!this.#options.sasl) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
const host = this.#host;
|
|
271
|
+
const port = this.#port;
|
|
272
|
+
const diagnosticContext = createDiagnosticContext({ connection: this, operation: 'reauthenticate', host, port });
|
|
273
|
+
this.#status = ConnectionStatuses.REAUTHENTICATING;
|
|
274
|
+
clearTimeout(this.#reauthenticationTimeout);
|
|
275
|
+
this.#authenticate(host, port, diagnosticContext);
|
|
276
|
+
}
|
|
264
277
|
#onResponse(request, callback, error, payload) {
|
|
265
278
|
clearTimeout(request.timeoutHandle);
|
|
266
279
|
request.timeoutHandle = null;
|
|
@@ -314,7 +327,9 @@ export class Connection extends TypedEventEmitter {
|
|
|
314
327
|
#sendRequest(request) {
|
|
315
328
|
connectionsApiChannel.start.publish(request.diagnostic);
|
|
316
329
|
try {
|
|
317
|
-
if (this.#status !== ConnectionStatuses.CONNECTED &&
|
|
330
|
+
if (this.#status !== ConnectionStatuses.CONNECTED &&
|
|
331
|
+
this.#status !== ConnectionStatuses.AUTHENTICATING &&
|
|
332
|
+
this.#status !== ConnectionStatuses.REAUTHENTICATING) {
|
|
318
333
|
request.callback(new NetworkError('Connection closed'), undefined);
|
|
319
334
|
return false;
|
|
320
335
|
}
|
|
@@ -387,17 +402,10 @@ export class Connection extends TypedEventEmitter {
|
|
|
387
402
|
return;
|
|
388
403
|
}
|
|
389
404
|
if (sessionLifetimeMs > 0) {
|
|
390
|
-
this.#reauthenticationTimeout = setTimeout(()
|
|
391
|
-
const diagnosticContext = createDiagnosticContext({
|
|
392
|
-
connection: this,
|
|
393
|
-
operation: 'reauthenticate',
|
|
394
|
-
host,
|
|
395
|
-
port
|
|
396
|
-
});
|
|
397
|
-
this.#authenticate(host, port, diagnosticContext);
|
|
398
|
-
}, Number(sessionLifetimeMs) * 0.8);
|
|
405
|
+
this.#reauthenticationTimeout = setTimeout(this.reauthenticate.bind(this), Number(sessionLifetimeMs) * 0.8);
|
|
399
406
|
}
|
|
400
|
-
if (this.#status === ConnectionStatuses.CONNECTED) {
|
|
407
|
+
if (this.#status === ConnectionStatuses.CONNECTED || this.#status === ConnectionStatuses.REAUTHENTICATING) {
|
|
408
|
+
this.#status = ConnectionStatuses.CONNECTED;
|
|
401
409
|
this.emit('sasl:authentication:extended', authBytes);
|
|
402
410
|
}
|
|
403
411
|
else {
|
|
@@ -24,11 +24,22 @@ export interface MessageConsumerMetadata {
|
|
|
24
24
|
generationId: number;
|
|
25
25
|
memberId: string;
|
|
26
26
|
}
|
|
27
|
+
export interface MessageJSON<Key = unknown, Value = unknown, HeaderKey = unknown, HeaderValue = unknown> {
|
|
28
|
+
key: Key;
|
|
29
|
+
value: Value;
|
|
30
|
+
headers: Array<[HeaderKey, HeaderValue]>;
|
|
31
|
+
topic: string;
|
|
32
|
+
partition: number;
|
|
33
|
+
timestamp: string;
|
|
34
|
+
offset: string;
|
|
35
|
+
metadata: Record<string, unknown>;
|
|
36
|
+
}
|
|
27
37
|
export interface Message<Key = Buffer, Value = Buffer, HeaderKey = Buffer, HeaderValue = Buffer> extends Required<MessageBase<Key, Value>> {
|
|
28
38
|
headers: Map<HeaderKey, HeaderValue>;
|
|
29
39
|
offset: bigint;
|
|
30
40
|
metadata: Record<string, unknown>;
|
|
31
41
|
commit(callback?: (error?: Error) => void): void | Promise<void>;
|
|
42
|
+
toJSON(): MessageJSON<Key, Value, HeaderKey, HeaderValue>;
|
|
32
43
|
}
|
|
33
44
|
export interface MessageRecord {
|
|
34
45
|
key?: Buffer;
|
|
@@ -17,7 +17,6 @@ export declare const kGetConnection: unique symbol;
|
|
|
17
17
|
export declare const kGetBootstrapConnection: unique symbol;
|
|
18
18
|
export declare const kOptions: unique symbol;
|
|
19
19
|
export declare const kConnections: unique symbol;
|
|
20
|
-
export declare const kFetchConnections: unique symbol;
|
|
21
20
|
export declare const kCreateConnectionPool: unique symbol;
|
|
22
21
|
export declare const kClosed: unique symbol;
|
|
23
22
|
export declare const kListApis: unique symbol;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { type CallbackWithPromise } from "../../apis/callbacks";
|
|
2
2
|
import { type FetchResponse } from "../../apis/consumer/fetch-v17";
|
|
3
|
-
import { type
|
|
4
|
-
import { Base, type BaseEvents, kFetchConnections } from "../base/base";
|
|
3
|
+
import { Base, type BaseEvents } from "../base/base";
|
|
5
4
|
import { MessagesStream } from "./messages-stream";
|
|
6
5
|
import { TopicsMap } from "./topics-map";
|
|
7
6
|
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";
|
|
@@ -20,11 +19,11 @@ export interface ConsumerEvents extends BaseEvents {
|
|
|
20
19
|
export declare class Consumer<Key = Buffer, Value = Buffer, HeaderKey = Buffer, HeaderValue = Buffer> extends Base<ConsumerOptions<Key, Value, HeaderKey, HeaderValue>, ConsumerEvents> {
|
|
21
20
|
#private;
|
|
22
21
|
groupId: string;
|
|
22
|
+
groupInstanceId: string | null;
|
|
23
23
|
generationId: number;
|
|
24
24
|
memberId: string | null;
|
|
25
25
|
topics: TopicsMap;
|
|
26
26
|
assignments: GroupAssignment[] | null;
|
|
27
|
-
[kFetchConnections]: ConnectionPool;
|
|
28
27
|
constructor(options: ConsumerOptions<Key, Value, HeaderKey, HeaderValue>);
|
|
29
28
|
get streamsCount(): number;
|
|
30
29
|
get lastHeartbeat(): Date | null;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Readable } from 'node:stream';
|
|
2
2
|
import { type CallbackWithPromise } from "../../apis/callbacks";
|
|
3
|
+
import { type ConnectionPool } from "../../network/connection-pool";
|
|
3
4
|
import { type Message } from "../../protocol/records";
|
|
4
5
|
import { kAutocommit, kInstance, kRefreshOffsetsAndFetch } from "../../symbols";
|
|
5
|
-
import { kInspect } from "../base/base";
|
|
6
|
+
import { kConnections, kInspect } from "../base/base";
|
|
6
7
|
import { type Consumer } from "./consumer";
|
|
7
8
|
import { type CommitOptionsPartition, type ConsumeOptions } from "./types";
|
|
8
9
|
export declare function noopDeserializer(data?: Buffer): Buffer | undefined;
|
|
@@ -10,6 +11,7 @@ export declare function defaultCorruptedMessageHandler(): boolean;
|
|
|
10
11
|
export declare class MessagesStream<Key, Value, HeaderKey, HeaderValue> extends Readable {
|
|
11
12
|
#private;
|
|
12
13
|
[kInstance]: number;
|
|
14
|
+
[kConnections]: ConnectionPool;
|
|
13
15
|
constructor(consumer: Consumer<Key, Value, HeaderKey, HeaderValue>, options: ConsumeOptions<Key, Value, HeaderKey, HeaderValue>);
|
|
14
16
|
get consumer(): Consumer<Key, Value, HeaderKey, HeaderValue>;
|
|
15
17
|
get offsetsToFetch(): Map<string, bigint>;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export declare const groupOptionsProperties: {
|
|
2
|
+
groupInstanceId: {
|
|
3
|
+
type: string;
|
|
4
|
+
pattern: string;
|
|
5
|
+
};
|
|
2
6
|
sessionTimeout: {
|
|
3
7
|
type: string;
|
|
4
8
|
minimum: number;
|
|
@@ -127,6 +131,10 @@ export declare const consumeOptionsProperties: {
|
|
|
127
131
|
export declare const groupOptionsSchema: {
|
|
128
132
|
type: string;
|
|
129
133
|
properties: {
|
|
134
|
+
groupInstanceId: {
|
|
135
|
+
type: string;
|
|
136
|
+
pattern: string;
|
|
137
|
+
};
|
|
130
138
|
sessionTimeout: {
|
|
131
139
|
type: string;
|
|
132
140
|
minimum: number;
|
|
@@ -233,6 +241,10 @@ export declare const consumeOptionsSchema: {
|
|
|
233
241
|
type: string;
|
|
234
242
|
minimum: number;
|
|
235
243
|
};
|
|
244
|
+
groupInstanceId: {
|
|
245
|
+
type: string;
|
|
246
|
+
pattern: string;
|
|
247
|
+
};
|
|
236
248
|
sessionTimeout: {
|
|
237
249
|
type: string;
|
|
238
250
|
minimum: number;
|
|
@@ -384,6 +396,10 @@ export declare const consumerOptionsSchema: {
|
|
|
384
396
|
type: string;
|
|
385
397
|
minimum: number;
|
|
386
398
|
};
|
|
399
|
+
groupInstanceId: {
|
|
400
|
+
type: string;
|
|
401
|
+
pattern: string;
|
|
402
|
+
};
|
|
387
403
|
sessionTimeout: {
|
|
388
404
|
type: string;
|
|
389
405
|
minimum: number;
|
|
@@ -495,6 +511,10 @@ export declare const fetchOptionsSchema: {
|
|
|
495
511
|
type: string;
|
|
496
512
|
minimum: number;
|
|
497
513
|
};
|
|
514
|
+
groupInstanceId: {
|
|
515
|
+
type: string;
|
|
516
|
+
pattern: string;
|
|
517
|
+
};
|
|
498
518
|
sessionTimeout: {
|
|
499
519
|
type: string;
|
|
500
520
|
minimum: number;
|
|
@@ -588,6 +608,9 @@ export declare const fetchOptionsSchema: {
|
|
|
588
608
|
required: string[];
|
|
589
609
|
};
|
|
590
610
|
};
|
|
611
|
+
connectionPool: {
|
|
612
|
+
type: string;
|
|
613
|
+
};
|
|
591
614
|
};
|
|
592
615
|
required: string[];
|
|
593
616
|
additionalProperties: boolean;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type FetchRequestTopic } from "../../apis/consumer/fetch-v17";
|
|
2
2
|
import { type GroupProtocols } from "../../apis/enumerations";
|
|
3
|
+
import { type ConnectionPool } from "../../network/connection-pool";
|
|
3
4
|
import { type KafkaRecord, type Message } from "../../protocol/records";
|
|
4
5
|
import { type BaseOptions, type ClusterMetadata, type TopicWithPartitionAndOffset } from "../base/types";
|
|
5
6
|
import { type Deserializers } from "../serde";
|
|
@@ -46,6 +47,7 @@ export type MessagesStreamFallbackMode = keyof typeof MessagesStreamFallbackMode
|
|
|
46
47
|
export type MessagesStreamFallbackModeValue = (typeof MessagesStreamFallbackModes)[keyof typeof MessagesStreamFallbackModes];
|
|
47
48
|
export interface GroupOptions {
|
|
48
49
|
groupProtocol?: typeof GroupProtocols.CLASSIC;
|
|
50
|
+
groupInstanceId?: string;
|
|
49
51
|
sessionTimeout?: number;
|
|
50
52
|
rebalanceTimeout?: number;
|
|
51
53
|
heartbeatInterval?: number;
|
|
@@ -54,6 +56,7 @@ export interface GroupOptions {
|
|
|
54
56
|
}
|
|
55
57
|
export interface ConsumerGroupOptions {
|
|
56
58
|
groupProtocol: typeof GroupProtocols.CONSUMER;
|
|
59
|
+
groupInstanceId?: string;
|
|
57
60
|
groupRemoteAssignor?: string;
|
|
58
61
|
rebalanceTimeout?: number;
|
|
59
62
|
}
|
|
@@ -81,6 +84,7 @@ export type ConsumerOptions<Key, Value, HeaderKey, HeaderValue> = BaseOptions &
|
|
|
81
84
|
export type FetchOptions<Key, Value, HeaderKey, HeaderValue> = Pick<ConsumeBaseOptions<Key, Value, HeaderKey, HeaderValue>, 'minBytes' | 'maxBytes' | 'maxWaitTime' | 'isolationLevel'> & {
|
|
82
85
|
node: number;
|
|
83
86
|
topics: FetchRequestTopic[];
|
|
87
|
+
connectionPool?: ConnectionPool;
|
|
84
88
|
};
|
|
85
89
|
export interface CommitOptionsPartition extends TopicWithPartitionAndOffset {
|
|
86
90
|
leaderEpoch: number;
|
|
@@ -4,8 +4,8 @@ import { type CallbackWithPromise } from "../apis/callbacks";
|
|
|
4
4
|
import { type Callback, type ResponseParser } from "../apis/definitions";
|
|
5
5
|
import { type SASLMechanismValue } from "../apis/enumerations";
|
|
6
6
|
import { type SaslAuthenticateResponse, type SASLAuthenticationAPI } from "../apis/security/sasl-authenticate-v2";
|
|
7
|
-
import { TypedEventEmitter, type TypedEvents } from "../events";
|
|
8
7
|
import { TimeoutError } from "../errors";
|
|
8
|
+
import { TypedEventEmitter, type TypedEvents } from "../events";
|
|
9
9
|
import { Writer } from "../protocol/writer";
|
|
10
10
|
export interface ConnectionEvents extends TypedEvents {
|
|
11
11
|
connecting: () => void;
|
|
@@ -40,6 +40,7 @@ export interface ConnectionOptions {
|
|
|
40
40
|
requestTimeout?: number;
|
|
41
41
|
maxInflights?: number;
|
|
42
42
|
tls?: TLSConnectionOptions;
|
|
43
|
+
ssl?: TLSConnectionOptions;
|
|
43
44
|
tlsServerName?: string | boolean;
|
|
44
45
|
sasl?: SASLOptions;
|
|
45
46
|
ownerId?: number;
|
|
@@ -62,6 +63,7 @@ export declare const ConnectionStatuses: {
|
|
|
62
63
|
readonly NONE: "none";
|
|
63
64
|
readonly CONNECTING: "connecting";
|
|
64
65
|
readonly AUTHENTICATING: "authenticating";
|
|
66
|
+
readonly REAUTHENTICATING: "reauthenticating";
|
|
65
67
|
readonly CONNECTED: "connected";
|
|
66
68
|
readonly CLOSED: "closed";
|
|
67
69
|
readonly CLOSING: "closing";
|
|
@@ -89,4 +91,5 @@ export declare class Connection extends TypedEventEmitter<ConnectionEvents> {
|
|
|
89
91
|
close(callback: CallbackWithPromise<void>): void;
|
|
90
92
|
close(): Promise<void>;
|
|
91
93
|
send<ReturnType>(apiKey: number, apiVersion: number, createPayload: () => Writer, responseParser: ResponseParser<ReturnType>, hasRequestHeaderTaggedFields: boolean, hasResponseHeaderTaggedFields: boolean, callback: Callback<ReturnType>): void;
|
|
94
|
+
reauthenticate(): void;
|
|
92
95
|
}
|
|
@@ -24,11 +24,22 @@ export interface MessageConsumerMetadata {
|
|
|
24
24
|
generationId: number;
|
|
25
25
|
memberId: string;
|
|
26
26
|
}
|
|
27
|
+
export interface MessageJSON<Key = unknown, Value = unknown, HeaderKey = unknown, HeaderValue = unknown> {
|
|
28
|
+
key: Key;
|
|
29
|
+
value: Value;
|
|
30
|
+
headers: Array<[HeaderKey, HeaderValue]>;
|
|
31
|
+
topic: string;
|
|
32
|
+
partition: number;
|
|
33
|
+
timestamp: string;
|
|
34
|
+
offset: string;
|
|
35
|
+
metadata: Record<string, unknown>;
|
|
36
|
+
}
|
|
27
37
|
export interface Message<Key = Buffer, Value = Buffer, HeaderKey = Buffer, HeaderValue = Buffer> extends Required<MessageBase<Key, Value>> {
|
|
28
38
|
headers: Map<HeaderKey, HeaderValue>;
|
|
29
39
|
offset: bigint;
|
|
30
40
|
metadata: Record<string, unknown>;
|
|
31
41
|
commit(callback?: (error?: Error) => void): void | Promise<void>;
|
|
42
|
+
toJSON(): MessageJSON<Key, Value, HeaderKey, HeaderValue>;
|
|
32
43
|
}
|
|
33
44
|
export interface MessageRecord {
|
|
34
45
|
key?: Buffer;
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export const name = "@platformatic/kafka";
|
|
2
|
-
export const version = "1.
|
|
2
|
+
export const version = "1.26.0";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/kafka",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.26.0",
|
|
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)",
|