@platformatic/kafka 1.0.0 → 1.2.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 -0
- package/dist/apis/admin/index.d.ts +38 -37
- package/dist/apis/admin/index.js +38 -37
- package/dist/apis/admin/list-groups-v4.d.ts +17 -0
- package/dist/apis/admin/list-groups-v4.js +40 -0
- package/dist/apis/consumer/fetch-v16.js +121 -0
- package/dist/apis/consumer/fetch-v17.d.ts +46 -0
- package/dist/apis/consumer/index.d.ts +11 -9
- package/dist/apis/consumer/index.js +11 -9
- package/dist/apis/consumer/list-offsets-v8.js +68 -0
- package/dist/apis/consumer/list-offsets-v9.d.ts +30 -0
- package/dist/apis/definitions.js +0 -1
- package/dist/apis/metadata/api-versions-v3.js +41 -0
- package/dist/apis/metadata/api-versions-v4.d.ts +17 -0
- package/dist/apis/metadata/find-coordinator-v4.js +50 -0
- package/dist/apis/metadata/find-coordinator-v5.d.ts +19 -0
- package/dist/apis/metadata/find-coordinator-v5.js +50 -0
- package/dist/apis/metadata/find-coordinator-v6.d.ts +19 -0
- package/dist/apis/metadata/index.d.ts +6 -3
- package/dist/apis/metadata/index.js +6 -3
- package/dist/apis/producer/index.d.ts +8 -6
- package/dist/apis/producer/index.js +8 -6
- package/dist/apis/producer/init-producer-id-v4.js +38 -0
- package/dist/apis/producer/init-producer-id-v5.d.ts +21 -0
- package/dist/apis/producer/produce-v10.js +104 -0
- package/dist/apis/producer/produce-v11.d.ts +29 -0
- package/dist/apis/security/index.d.ts +2 -2
- package/dist/apis/security/index.js +2 -2
- package/dist/apis/telemetry/index.d.ts +3 -3
- package/dist/apis/telemetry/index.js +3 -3
- package/dist/clients/admin/admin.js +58 -22
- package/dist/clients/base/base.d.ts +19 -3
- package/dist/clients/base/base.js +93 -13
- package/dist/clients/base/options.d.ts +2 -0
- package/dist/clients/base/options.js +5 -0
- package/dist/clients/callbacks.d.ts +1 -0
- package/dist/clients/callbacks.js +3 -2
- package/dist/clients/consumer/consumer.d.ts +1 -1
- package/dist/clients/consumer/consumer.js +166 -105
- package/dist/clients/consumer/messages-stream.d.ts +1 -0
- package/dist/clients/consumer/messages-stream.js +81 -47
- package/dist/clients/consumer/options.d.ts +3 -0
- package/dist/clients/consumer/options.js +1 -0
- package/dist/clients/consumer/types.d.ts +8 -3
- package/dist/clients/producer/producer.js +49 -28
- package/dist/diagnostic.d.ts +47 -0
- package/dist/diagnostic.js +38 -0
- package/dist/errors.d.ts +5 -1
- package/dist/errors.js +12 -6
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/network/connection-pool.d.ts +2 -1
- package/dist/network/connection-pool.js +36 -25
- package/dist/network/connection.d.ts +2 -2
- package/dist/network/connection.js +135 -81
- package/dist/protocol/compression.js +8 -8
- package/dist/protocol/reader.js +0 -1
- package/dist/protocol/records.js +0 -3
- package/dist/protocol/sasl/plain.d.ts +1 -1
- package/dist/protocol/sasl/scram-sha.d.ts +11 -4
- package/dist/protocol/sasl/scram-sha.js +8 -2
- package/dist/symbols.d.ts +1 -0
- package/dist/symbols.js +2 -0
- package/package.json +3 -3
- /package/dist/apis/admin/{alter-client-quotas.d.ts → alter-client-quotas-v1.d.ts} +0 -0
- /package/dist/apis/admin/{alter-client-quotas.js → alter-client-quotas-v1.js} +0 -0
- /package/dist/apis/admin/{alter-configs.d.ts → alter-configs-v2.d.ts} +0 -0
- /package/dist/apis/admin/{alter-configs.js → alter-configs-v2.js} +0 -0
- /package/dist/apis/admin/{alter-partition-reassignments.d.ts → alter-partition-reassignments-v0.d.ts} +0 -0
- /package/dist/apis/admin/{alter-partition-reassignments.js → alter-partition-reassignments-v0.js} +0 -0
- /package/dist/apis/admin/{alter-partition.d.ts → alter-partition-v3.d.ts} +0 -0
- /package/dist/apis/admin/{alter-partition.js → alter-partition-v3.js} +0 -0
- /package/dist/apis/admin/{alter-replica-log-dirs.d.ts → alter-replica-log-dirs-v2.d.ts} +0 -0
- /package/dist/apis/admin/{alter-replica-log-dirs.js → alter-replica-log-dirs-v2.js} +0 -0
- /package/dist/apis/admin/{alter-user-scram-credentials.d.ts → alter-user-scram-credentials-v0.d.ts} +0 -0
- /package/dist/apis/admin/{alter-user-scram-credentials.js → alter-user-scram-credentials-v0.js} +0 -0
- /package/dist/apis/admin/{consumer-group-describe.d.ts → consumer-group-describe-v0.d.ts} +0 -0
- /package/dist/apis/admin/{consumer-group-describe.js → consumer-group-describe-v0.js} +0 -0
- /package/dist/apis/admin/{create-acls.d.ts → create-acls-v3.d.ts} +0 -0
- /package/dist/apis/admin/{create-acls.js → create-acls-v3.js} +0 -0
- /package/dist/apis/admin/{create-delegation-token.d.ts → create-delegation-token-v3.d.ts} +0 -0
- /package/dist/apis/admin/{create-delegation-token.js → create-delegation-token-v3.js} +0 -0
- /package/dist/apis/admin/{create-partitions.d.ts → create-partitions-v3.d.ts} +0 -0
- /package/dist/apis/admin/{create-partitions.js → create-partitions-v3.js} +0 -0
- /package/dist/apis/admin/{create-topics.d.ts → create-topics-v7.d.ts} +0 -0
- /package/dist/apis/admin/{create-topics.js → create-topics-v7.js} +0 -0
- /package/dist/apis/admin/{delete-acls.d.ts → delete-acls-v3.d.ts} +0 -0
- /package/dist/apis/admin/{delete-acls.js → delete-acls-v3.js} +0 -0
- /package/dist/apis/admin/{delete-groups.d.ts → delete-groups-v2.d.ts} +0 -0
- /package/dist/apis/admin/{delete-groups.js → delete-groups-v2.js} +0 -0
- /package/dist/apis/admin/{delete-records.d.ts → delete-records-v2.d.ts} +0 -0
- /package/dist/apis/admin/{delete-records.js → delete-records-v2.js} +0 -0
- /package/dist/apis/admin/{delete-topics.d.ts → delete-topics-v6.d.ts} +0 -0
- /package/dist/apis/admin/{delete-topics.js → delete-topics-v6.js} +0 -0
- /package/dist/apis/admin/{describe-acls.d.ts → describe-acls-v3.d.ts} +0 -0
- /package/dist/apis/admin/{describe-acls.js → describe-acls-v3.js} +0 -0
- /package/dist/apis/admin/{describe-client-quotas.d.ts → describe-client-quotas-v0.d.ts} +0 -0
- /package/dist/apis/admin/{describe-client-quotas.js → describe-client-quotas-v0.js} +0 -0
- /package/dist/apis/admin/{describe-cluster.d.ts → describe-cluster-v1.d.ts} +0 -0
- /package/dist/apis/admin/{describe-cluster.js → describe-cluster-v1.js} +0 -0
- /package/dist/apis/admin/{describe-configs.d.ts → describe-configs-v4.d.ts} +0 -0
- /package/dist/apis/admin/{describe-configs.js → describe-configs-v4.js} +0 -0
- /package/dist/apis/admin/{describe-delegation-token.d.ts → describe-delegation-token-v3.d.ts} +0 -0
- /package/dist/apis/admin/{describe-delegation-token.js → describe-delegation-token-v3.js} +0 -0
- /package/dist/apis/admin/{describe-groups.d.ts → describe-groups-v5.d.ts} +0 -0
- /package/dist/apis/admin/{describe-groups.js → describe-groups-v5.js} +0 -0
- /package/dist/apis/admin/{describe-log-dirs.d.ts → describe-log-dirs-v4.d.ts} +0 -0
- /package/dist/apis/admin/{describe-log-dirs.js → describe-log-dirs-v4.js} +0 -0
- /package/dist/apis/admin/{describe-producers.d.ts → describe-producers-v0.d.ts} +0 -0
- /package/dist/apis/admin/{describe-producers.js → describe-producers-v0.js} +0 -0
- /package/dist/apis/admin/{describe-quorum.d.ts → describe-quorum-v2.d.ts} +0 -0
- /package/dist/apis/admin/{describe-quorum.js → describe-quorum-v2.js} +0 -0
- /package/dist/apis/admin/{describe-topic-partitions.d.ts → describe-topic-partitions-v0.d.ts} +0 -0
- /package/dist/apis/admin/{describe-topic-partitions.js → describe-topic-partitions-v0.js} +0 -0
- /package/dist/apis/admin/{describe-transactions.d.ts → describe-transactions-v0.d.ts} +0 -0
- /package/dist/apis/admin/{describe-transactions.js → describe-transactions-v0.js} +0 -0
- /package/dist/apis/admin/{describe-user-scram-credentials.d.ts → describe-user-scram-credentials-v0.d.ts} +0 -0
- /package/dist/apis/admin/{describe-user-scram-credentials.js → describe-user-scram-credentials-v0.js} +0 -0
- /package/dist/apis/admin/{envelope.d.ts → envelope-v0.d.ts} +0 -0
- /package/dist/apis/admin/{envelope.js → envelope-v0.js} +0 -0
- /package/dist/apis/admin/{expire-delegation-token.d.ts → expire-delegation-token-v2.d.ts} +0 -0
- /package/dist/apis/admin/{expire-delegation-token.js → expire-delegation-token-v2.js} +0 -0
- /package/dist/apis/admin/{incremental-alter-configs.d.ts → incremental-alter-configs-v1.d.ts} +0 -0
- /package/dist/apis/admin/{incremental-alter-configs.js → incremental-alter-configs-v1.js} +0 -0
- /package/dist/apis/admin/{list-groups.d.ts → list-groups-v5.d.ts} +0 -0
- /package/dist/apis/admin/{list-groups.js → list-groups-v5.js} +0 -0
- /package/dist/apis/admin/{list-partition-reassignments.d.ts → list-partition-reassignments-v0.d.ts} +0 -0
- /package/dist/apis/admin/{list-partition-reassignments.js → list-partition-reassignments-v0.js} +0 -0
- /package/dist/apis/admin/{list-transactions.d.ts → list-transactions-v1.d.ts} +0 -0
- /package/dist/apis/admin/{list-transactions.js → list-transactions-v1.js} +0 -0
- /package/dist/apis/admin/{offset-delete.d.ts → offset-delete-v0.d.ts} +0 -0
- /package/dist/apis/admin/{offset-delete.js → offset-delete-v0.js} +0 -0
- /package/dist/apis/admin/{renew-delegation-token.d.ts → renew-delegation-token-v2.d.ts} +0 -0
- /package/dist/apis/admin/{renew-delegation-token.js → renew-delegation-token-v2.js} +0 -0
- /package/dist/apis/admin/{unregister-broker.d.ts → unregister-broker-v0.d.ts} +0 -0
- /package/dist/apis/admin/{unregister-broker.js → unregister-broker-v0.js} +0 -0
- /package/dist/apis/admin/{update-features.d.ts → update-features-v1.d.ts} +0 -0
- /package/dist/apis/admin/{update-features.js → update-features-v1.js} +0 -0
- /package/dist/apis/consumer/{consumer-group-heartbeat.d.ts → consumer-group-heartbeat-v0.d.ts} +0 -0
- /package/dist/apis/consumer/{consumer-group-heartbeat.js → consumer-group-heartbeat-v0.js} +0 -0
- /package/dist/apis/consumer/{fetch.d.ts → fetch-v16.d.ts} +0 -0
- /package/dist/apis/consumer/{fetch.js → fetch-v17.js} +0 -0
- /package/dist/apis/consumer/{heartbeat.d.ts → heartbeat-v4.d.ts} +0 -0
- /package/dist/apis/consumer/{heartbeat.js → heartbeat-v4.js} +0 -0
- /package/dist/apis/consumer/{join-group.d.ts → join-group-v9.d.ts} +0 -0
- /package/dist/apis/consumer/{join-group.js → join-group-v9.js} +0 -0
- /package/dist/apis/consumer/{leave-group.d.ts → leave-group-v5.d.ts} +0 -0
- /package/dist/apis/consumer/{leave-group.js → leave-group-v5.js} +0 -0
- /package/dist/apis/consumer/{list-offsets.d.ts → list-offsets-v8.d.ts} +0 -0
- /package/dist/apis/consumer/{list-offsets.js → list-offsets-v9.js} +0 -0
- /package/dist/apis/consumer/{offset-commit.d.ts → offset-commit-v9.d.ts} +0 -0
- /package/dist/apis/consumer/{offset-commit.js → offset-commit-v9.js} +0 -0
- /package/dist/apis/consumer/{offset-fetch.d.ts → offset-fetch-v9.d.ts} +0 -0
- /package/dist/apis/consumer/{offset-fetch.js → offset-fetch-v9.js} +0 -0
- /package/dist/apis/consumer/{sync-group.d.ts → sync-group-v5.d.ts} +0 -0
- /package/dist/apis/consumer/{sync-group.js → sync-group-v5.js} +0 -0
- /package/dist/apis/metadata/{api-versions.d.ts → api-versions-v3.d.ts} +0 -0
- /package/dist/apis/metadata/{api-versions.js → api-versions-v4.js} +0 -0
- /package/dist/apis/metadata/{find-coordinator.d.ts → find-coordinator-v4.d.ts} +0 -0
- /package/dist/apis/metadata/{find-coordinator.js → find-coordinator-v6.js} +0 -0
- /package/dist/apis/metadata/{metadata.d.ts → metadata-v12.d.ts} +0 -0
- /package/dist/apis/metadata/{metadata.js → metadata-v12.js} +0 -0
- /package/dist/apis/producer/{add-offsets-to-txn.d.ts → add-offsets-to-txn-v4.d.ts} +0 -0
- /package/dist/apis/producer/{add-offsets-to-txn.js → add-offsets-to-txn-v4.js} +0 -0
- /package/dist/apis/producer/{add-partitions-to-txn.d.ts → add-partitions-to-txn-v5.d.ts} +0 -0
- /package/dist/apis/producer/{add-partitions-to-txn.js → add-partitions-to-txn-v5.js} +0 -0
- /package/dist/apis/producer/{end-txn.d.ts → end-txn-v4.d.ts} +0 -0
- /package/dist/apis/producer/{end-txn.js → end-txn-v4.js} +0 -0
- /package/dist/apis/producer/{init-producer-id.d.ts → init-producer-id-v4.d.ts} +0 -0
- /package/dist/apis/producer/{init-producer-id.js → init-producer-id-v5.js} +0 -0
- /package/dist/apis/producer/{produce.d.ts → produce-v10.d.ts} +0 -0
- /package/dist/apis/producer/{produce.js → produce-v11.js} +0 -0
- /package/dist/apis/producer/{txn-offset-commit.d.ts → txn-offset-commit-v4.d.ts} +0 -0
- /package/dist/apis/producer/{txn-offset-commit.js → txn-offset-commit-v4.js} +0 -0
- /package/dist/apis/security/{sasl-authenticate.d.ts → sasl-authenticate-v2.d.ts} +0 -0
- /package/dist/apis/security/{sasl-authenticate.js → sasl-authenticate-v2.js} +0 -0
- /package/dist/apis/security/{sasl-handshake.d.ts → sasl-handshake-v1.d.ts} +0 -0
- /package/dist/apis/security/{sasl-handshake.js → sasl-handshake-v1.js} +0 -0
- /package/dist/apis/telemetry/{get-telemetry-subscriptions.d.ts → get-telemetry-subscriptions-v0.d.ts} +0 -0
- /package/dist/apis/telemetry/{get-telemetry-subscriptions.js → get-telemetry-subscriptions-v0.js} +0 -0
- /package/dist/apis/telemetry/{list-client-metrics-resources.d.ts → list-client-metrics-resources-v0.d.ts} +0 -0
- /package/dist/apis/telemetry/{list-client-metrics-resources.js → list-client-metrics-resources-v0.js} +0 -0
- /package/dist/apis/telemetry/{push-telemetry.d.ts → push-telemetry-v0.d.ts} +0 -0
- /package/dist/apis/telemetry/{push-telemetry.js → push-telemetry-v0.js} +0 -0
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
import { Readable } from 'node:stream';
|
|
2
2
|
import { ListOffsetTimestamps } from "../../apis/enumerations.js";
|
|
3
|
+
import { consumerReceivesChannel, createDiagnosticContext, notifyCreation } from "../../diagnostic.js";
|
|
3
4
|
import { UserError } from "../../errors.js";
|
|
4
5
|
import { kInspect, kPrometheus } from "../base/base.js";
|
|
5
6
|
import { createPromisifiedCallback, kCallbackPromise, noopCallback } from "../callbacks.js";
|
|
6
7
|
import { ensureMetric } from "../metrics.js";
|
|
8
|
+
import { defaultConsumerOptions } from "./options.js";
|
|
7
9
|
import { MessagesStreamFallbackModes, MessagesStreamModes } from "./types.js";
|
|
8
10
|
// Don't move this function as being in the same file will enable V8 to remove.
|
|
9
11
|
// For futher info, ask Matteo.
|
|
10
|
-
/* c8 ignore next 3 */
|
|
12
|
+
/* c8 ignore next 3 - Fallback deserializer, nothing to really test */
|
|
11
13
|
export function noopDeserializer(data) {
|
|
12
14
|
return data;
|
|
13
15
|
}
|
|
16
|
+
export function defaultCorruptedMessageHandler() {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
14
19
|
export class MessagesStream extends Readable {
|
|
15
20
|
#consumer;
|
|
16
21
|
#mode;
|
|
@@ -30,16 +35,17 @@ export class MessagesStream extends Readable {
|
|
|
30
35
|
#shouldClose;
|
|
31
36
|
#closeCallbacks;
|
|
32
37
|
#metricsConsumedMessages;
|
|
38
|
+
#corruptedMessageHandler;
|
|
33
39
|
constructor(consumer, options) {
|
|
34
|
-
const { autocommit, mode, fallbackMode, offsets, deserializers, ...
|
|
40
|
+
const { autocommit, mode, fallbackMode, offsets, deserializers, onCorruptedMessage, ...otherOptions } = options;
|
|
35
41
|
if (offsets && mode !== MessagesStreamModes.MANUAL) {
|
|
36
42
|
throw new UserError('Cannot specify offsets when the stream mode is not MANUAL.');
|
|
37
43
|
}
|
|
38
44
|
if (!offsets && mode === MessagesStreamModes.MANUAL) {
|
|
39
45
|
throw new UserError('Must specify offsets when the stream mode is MANUAL.');
|
|
40
46
|
}
|
|
41
|
-
/* c8 ignore next
|
|
42
|
-
super({ objectMode: true, highWaterMark: options.highWaterMark ??
|
|
47
|
+
/* c8 ignore next - Unless is initialized directly, highWaterMark is always defined */
|
|
48
|
+
super({ objectMode: true, highWaterMark: options.highWaterMark ?? defaultConsumerOptions.highWaterMark });
|
|
43
49
|
this.#consumer = consumer;
|
|
44
50
|
this.#mode = mode ?? MessagesStreamModes.LATEST;
|
|
45
51
|
this.#fallbackMode = fallbackMode ?? MessagesStreamFallbackModes.LATEST;
|
|
@@ -54,6 +60,7 @@ export class MessagesStream extends Readable {
|
|
|
54
60
|
this.#autocommitInflight = false;
|
|
55
61
|
this.#shouldClose = false;
|
|
56
62
|
this.#closeCallbacks = [];
|
|
63
|
+
this.#corruptedMessageHandler = onCorruptedMessage ?? defaultCorruptedMessageHandler;
|
|
57
64
|
// Restore offsets
|
|
58
65
|
this.#offsetsToFetch = new Map();
|
|
59
66
|
if (offsets) {
|
|
@@ -62,9 +69,8 @@ export class MessagesStream extends Readable {
|
|
|
62
69
|
}
|
|
63
70
|
}
|
|
64
71
|
// Clone the rest of the options so the user can never mutate them
|
|
65
|
-
this.#options = structuredClone(
|
|
72
|
+
this.#options = structuredClone(otherOptions);
|
|
66
73
|
// Start the autocommit interval
|
|
67
|
-
/* c8 ignore next */
|
|
68
74
|
if (typeof autocommit === 'number' && autocommit > 0) {
|
|
69
75
|
this.#autocommitInterval = setInterval(this.#autocommit.bind(this), autocommit);
|
|
70
76
|
}
|
|
@@ -76,7 +82,7 @@ export class MessagesStream extends Readable {
|
|
|
76
82
|
// having some.
|
|
77
83
|
this.#consumer.on('consumer:group:join', () => {
|
|
78
84
|
this.#refreshOffsets((error) => {
|
|
79
|
-
/* c8 ignore next 4 */
|
|
85
|
+
/* c8 ignore next 4 - Hard to test */
|
|
80
86
|
if (error) {
|
|
81
87
|
this.destroy(error);
|
|
82
88
|
return;
|
|
@@ -87,6 +93,7 @@ export class MessagesStream extends Readable {
|
|
|
87
93
|
if (consumer[kPrometheus]) {
|
|
88
94
|
this.#metricsConsumedMessages = ensureMetric(consumer[kPrometheus], 'Counter', 'kafka_consumed_messages', 'Number of consumed Kafka messages');
|
|
89
95
|
}
|
|
96
|
+
notifyCreation('messages-stream', this);
|
|
90
97
|
}
|
|
91
98
|
close(callback) {
|
|
92
99
|
if (!callback) {
|
|
@@ -111,7 +118,7 @@ export class MessagesStream extends Readable {
|
|
|
111
118
|
this.removeAllListeners('readable');
|
|
112
119
|
this.resume();
|
|
113
120
|
}
|
|
114
|
-
/* c8 ignore next 3 */
|
|
121
|
+
/* c8 ignore next 3 - Hard to test */
|
|
115
122
|
this.once('error', (error) => {
|
|
116
123
|
callback(error);
|
|
117
124
|
});
|
|
@@ -131,23 +138,23 @@ export class MessagesStream extends Readable {
|
|
|
131
138
|
});
|
|
132
139
|
return callback[kCallbackPromise];
|
|
133
140
|
}
|
|
134
|
-
/* c8 ignore next 3 */
|
|
141
|
+
/* c8 ignore next 3 - Only forwards to Node.js implementation - Inserted here to please Typescript */
|
|
135
142
|
addListener(event, listener) {
|
|
136
143
|
return super.addListener(event, listener);
|
|
137
144
|
}
|
|
138
|
-
/* c8 ignore next 3 */
|
|
145
|
+
/* c8 ignore next 3 - Only forwards to Node.js implementation - Inserted here to please Typescript */
|
|
139
146
|
on(event, listener) {
|
|
140
147
|
return super.on(event, listener);
|
|
141
148
|
}
|
|
142
|
-
/* c8 ignore next 3 */
|
|
149
|
+
/* c8 ignore next 3 - Only forwards to Node.js implementation - Inserted here to please Typescript */
|
|
143
150
|
once(event, listener) {
|
|
144
151
|
return super.once(event, listener);
|
|
145
152
|
}
|
|
146
|
-
/* c8 ignore next 3 */
|
|
153
|
+
/* c8 ignore next 3 - Only forwards to Node.js implementation - Inserted here to please Typescript */
|
|
147
154
|
prependListener(event, listener) {
|
|
148
155
|
return super.prependListener(event, listener);
|
|
149
156
|
}
|
|
150
|
-
/* c8 ignore next 3 */
|
|
157
|
+
/* c8 ignore next 3 - Only forwards to Node.js implementation - Inserted here to please Typescript */
|
|
151
158
|
prependOnceListener(event, listener) {
|
|
152
159
|
return super.prependOnceListener(event, listener);
|
|
153
160
|
}
|
|
@@ -167,7 +174,7 @@ export class MessagesStream extends Readable {
|
|
|
167
174
|
this.#fetch();
|
|
168
175
|
}
|
|
169
176
|
#fetch() {
|
|
170
|
-
/* c8 ignore next 4 */
|
|
177
|
+
/* c8 ignore next 4 - Hard to test */
|
|
171
178
|
if (this.#shouldClose || this.closed || this.destroyed) {
|
|
172
179
|
this.push(null);
|
|
173
180
|
return;
|
|
@@ -175,7 +182,7 @@ export class MessagesStream extends Readable {
|
|
|
175
182
|
this.#consumer.metadata({ topics: this.#consumer.topics.current }, (error, metadata) => {
|
|
176
183
|
if (error) {
|
|
177
184
|
// The stream has been closed, ignore any error
|
|
178
|
-
/* c8 ignore next 4 */
|
|
185
|
+
/* c8 ignore next 4 - Hard to test */
|
|
179
186
|
if (this.#shouldClose) {
|
|
180
187
|
this.push(null);
|
|
181
188
|
return;
|
|
@@ -183,7 +190,7 @@ export class MessagesStream extends Readable {
|
|
|
183
190
|
this.destroy(error);
|
|
184
191
|
return;
|
|
185
192
|
}
|
|
186
|
-
/* c8 ignore next 4 */
|
|
193
|
+
/* c8 ignore next 4 - Hard to test */
|
|
187
194
|
if (this.#shouldClose || this.closed || this.destroyed) {
|
|
188
195
|
this.push(null);
|
|
189
196
|
return;
|
|
@@ -191,6 +198,7 @@ export class MessagesStream extends Readable {
|
|
|
191
198
|
const requests = new Map();
|
|
192
199
|
const topicIds = new Map();
|
|
193
200
|
// Group topic-partitions by the destination broker
|
|
201
|
+
const requestedOffsets = new Map();
|
|
194
202
|
for (const topic of this.#topics) {
|
|
195
203
|
const assignment = this.#assignmentsForTopic(topic);
|
|
196
204
|
// This consumer has no assignment for the topic, continue
|
|
@@ -210,13 +218,14 @@ export class MessagesStream extends Readable {
|
|
|
210
218
|
}
|
|
211
219
|
const topicId = metadata.topics.get(topic).id;
|
|
212
220
|
topicIds.set(topicId, topic);
|
|
221
|
+
const fetchOffset = this.#offsetsToFetch.get(`${topic}:${partition}`);
|
|
222
|
+
requestedOffsets.set(`${topic}:${partition}`, fetchOffset);
|
|
213
223
|
leaderRequests.push({
|
|
214
224
|
topicId,
|
|
215
225
|
partitions: [
|
|
216
226
|
{
|
|
217
227
|
partition,
|
|
218
|
-
|
|
219
|
-
fetchOffset: this.#offsetsToFetch.get(`${topic}:${partition}`) ?? 0n,
|
|
228
|
+
fetchOffset,
|
|
220
229
|
partitionMaxBytes: this.#options.maxBytes,
|
|
221
230
|
currentLeaderEpoch: -1,
|
|
222
231
|
lastFetchedEpoch: -1
|
|
@@ -231,7 +240,7 @@ export class MessagesStream extends Readable {
|
|
|
231
240
|
this.#inflightNodes.delete(leader);
|
|
232
241
|
if (error) {
|
|
233
242
|
// The stream has been closed, ignore the error
|
|
234
|
-
/* c8 ignore next 4 */
|
|
243
|
+
/* c8 ignore next 4 - Hard to test */
|
|
235
244
|
if (this.#shouldClose) {
|
|
236
245
|
this.push(null);
|
|
237
246
|
return;
|
|
@@ -247,29 +256,44 @@ export class MessagesStream extends Readable {
|
|
|
247
256
|
}
|
|
248
257
|
return;
|
|
249
258
|
}
|
|
250
|
-
this.#pushRecords(metadata, topicIds, response);
|
|
259
|
+
this.#pushRecords(metadata, topicIds, response, requestedOffsets);
|
|
251
260
|
});
|
|
252
261
|
}
|
|
253
262
|
});
|
|
254
263
|
}
|
|
255
|
-
#pushRecords(metadata, topicIds, response) {
|
|
264
|
+
#pushRecords(metadata, topicIds, response, requestedOffsets) {
|
|
256
265
|
const autocommit = this.#autocommitEnabled;
|
|
257
266
|
let canPush = true;
|
|
258
267
|
const keyDeserializer = this.#keyDeserializer;
|
|
259
268
|
const valueDeserializer = this.#valueDeserializer;
|
|
260
269
|
const headerKeyDeserializer = this.#headerKeyDeserializer;
|
|
261
270
|
const headerValueDeserializer = this.#headerValueDeserializer;
|
|
271
|
+
let diagnosticContext;
|
|
262
272
|
// Parse results
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
273
|
+
for (const topicResponse of response.responses) {
|
|
274
|
+
const topic = topicIds.get(topicResponse.topicId);
|
|
275
|
+
for (const { records, partitionIndex: partition } of topicResponse.partitions) {
|
|
276
|
+
if (!records) {
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
const firstTimestamp = records.firstTimestamp;
|
|
280
|
+
const firstOffset = records.firstOffset;
|
|
281
|
+
const leaderEpoch = metadata.topics.get(topic).partitions[partition].leaderEpoch;
|
|
282
|
+
for (const record of records.records) {
|
|
283
|
+
const offset = records.firstOffset + BigInt(record.offsetDelta);
|
|
284
|
+
if (offset < requestedOffsets.get(`${topic}:${partition}`)) {
|
|
285
|
+
// Thi is a duplicate message, ignore it
|
|
268
286
|
continue;
|
|
269
287
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
288
|
+
diagnosticContext = createDiagnosticContext({
|
|
289
|
+
client: this.#consumer,
|
|
290
|
+
stream: this,
|
|
291
|
+
operation: 'receive',
|
|
292
|
+
raw: record
|
|
293
|
+
});
|
|
294
|
+
consumerReceivesChannel.start.publish(diagnosticContext);
|
|
295
|
+
const commit = autocommit ? noopCallback : this.#commit.bind(this, topic, partition, offset, leaderEpoch);
|
|
296
|
+
try {
|
|
273
297
|
const headers = new Map();
|
|
274
298
|
for (const [headerKey, headerValue] of record.headers) {
|
|
275
299
|
headers.set(headerKeyDeserializer(headerKey), headerValueDeserializer(headerValue));
|
|
@@ -277,33 +301,43 @@ export class MessagesStream extends Readable {
|
|
|
277
301
|
const key = keyDeserializer(record.key, headers);
|
|
278
302
|
const value = valueDeserializer(record.value, headers);
|
|
279
303
|
this.#metricsConsumedMessages?.inc();
|
|
280
|
-
|
|
304
|
+
const message = {
|
|
281
305
|
key,
|
|
282
306
|
value,
|
|
283
307
|
headers,
|
|
284
308
|
topic,
|
|
285
309
|
partition,
|
|
286
310
|
timestamp: firstTimestamp + record.timestampDelta,
|
|
287
|
-
offset
|
|
288
|
-
commit
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
311
|
+
offset,
|
|
312
|
+
commit
|
|
313
|
+
};
|
|
314
|
+
diagnosticContext.result = message;
|
|
315
|
+
consumerReceivesChannel.asyncStart.publish(diagnosticContext);
|
|
316
|
+
canPush = this.push(message);
|
|
317
|
+
consumerReceivesChannel.asyncEnd.publish(diagnosticContext);
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
const shouldDestroy = this.#corruptedMessageHandler(record, topic, partition, firstTimestamp, firstOffset, commit);
|
|
321
|
+
if (shouldDestroy) {
|
|
322
|
+
diagnosticContext.error = error;
|
|
323
|
+
consumerReceivesChannel.error.publish(diagnosticContext);
|
|
324
|
+
this.destroy(new UserError('Failed to deserialize a message.', { cause: error }));
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
292
327
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
this.#offsetsToFetch.set(`${topic}:${partition}`, lastOffset + 1n);
|
|
296
|
-
// Autocommit if needed
|
|
297
|
-
if (autocommit) {
|
|
298
|
-
this.#offsetsToCommit.set(`${topic}:${partition}`, { topic, partition, offset: lastOffset, leaderEpoch });
|
|
328
|
+
finally {
|
|
329
|
+
consumerReceivesChannel.end.publish(diagnosticContext);
|
|
299
330
|
}
|
|
300
331
|
}
|
|
332
|
+
// Track the last read offset
|
|
333
|
+
const lastOffset = records.firstOffset + BigInt(records.lastOffsetDelta);
|
|
334
|
+
this.#offsetsToFetch.set(`${topic}:${partition}`, lastOffset + 1n);
|
|
335
|
+
// Autocommit if needed
|
|
336
|
+
if (autocommit) {
|
|
337
|
+
this.#offsetsToCommit.set(`${topic}:${partition}`, { topic, partition, offset: lastOffset, leaderEpoch });
|
|
338
|
+
}
|
|
301
339
|
}
|
|
302
340
|
}
|
|
303
|
-
catch (error) {
|
|
304
|
-
this.destroy(new UserError('Failed to deserialize a message.', { cause: error }));
|
|
305
|
-
return;
|
|
306
|
-
}
|
|
307
341
|
if (this.#autocommitEnabled && !this.#autocommitInterval) {
|
|
308
342
|
this.#autocommit();
|
|
309
343
|
}
|
|
@@ -339,6 +373,7 @@ export class MessagesStream extends Readable {
|
|
|
339
373
|
});
|
|
340
374
|
}
|
|
341
375
|
#refreshOffsets(callback) {
|
|
376
|
+
/* c8 ignore next 4 - Hard to test */
|
|
342
377
|
if (this.#topics.length === 0) {
|
|
343
378
|
callback(null);
|
|
344
379
|
return;
|
|
@@ -412,8 +447,7 @@ export class MessagesStream extends Readable {
|
|
|
412
447
|
}
|
|
413
448
|
this.#closeCallbacks = [];
|
|
414
449
|
}
|
|
415
|
-
|
|
416
|
-
/* c8 ignore next 3 */
|
|
450
|
+
/* c8 ignore next 3 - This is a private API used to debug during development */
|
|
417
451
|
[kInspect](...args) {
|
|
418
452
|
this.#consumer[kInspect](...args);
|
|
419
453
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type FetchRequestTopic } from '../../apis/consumer/fetch.ts';
|
|
1
|
+
import { type FetchRequestTopic } from '../../apis/consumer/fetch-v17.ts';
|
|
2
2
|
import { type FetchIsolationLevel } from '../../apis/enumerations.ts';
|
|
3
|
+
import { type KafkaRecord, type Message } from '../../protocol/records.ts';
|
|
3
4
|
import { type BaseOptions, type TopicWithPartitionAndOffset } from '../base/types.ts';
|
|
4
5
|
import { type Deserializers } from '../serde.ts';
|
|
5
6
|
export interface GroupProtocolSubscription {
|
|
@@ -16,6 +17,7 @@ export interface ExtendedGroupProtocolSubscription extends Omit<GroupProtocolSub
|
|
|
16
17
|
memberId: string;
|
|
17
18
|
}
|
|
18
19
|
export type Offsets = Map<string, bigint[]>;
|
|
20
|
+
export type CorruptedMessageHandler = (record: KafkaRecord, topic: string, partition: number, firstTimestamp: bigint, firstOffset: bigint, commit: Message['commit']) => boolean;
|
|
19
21
|
export declare const MessagesStreamModes: {
|
|
20
22
|
readonly LATEST: "latest";
|
|
21
23
|
readonly EARLIEST: "earliest";
|
|
@@ -23,12 +25,14 @@ export declare const MessagesStreamModes: {
|
|
|
23
25
|
readonly MANUAL: "manual";
|
|
24
26
|
};
|
|
25
27
|
export type MessagesStreamMode = keyof typeof MessagesStreamModes;
|
|
28
|
+
export type MessagesStreamModeValue = (typeof MessagesStreamModes)[keyof typeof MessagesStreamModes];
|
|
26
29
|
export declare const MessagesStreamFallbackModes: {
|
|
27
30
|
readonly LATEST: "latest";
|
|
28
31
|
readonly EARLIEST: "earliest";
|
|
29
32
|
readonly FAIL: "fail";
|
|
30
33
|
};
|
|
31
34
|
export type MessagesStreamFallbackMode = keyof typeof MessagesStreamFallbackModes;
|
|
35
|
+
export type MessagesStreamFallbackModeValue = (typeof MessagesStreamFallbackModes)[keyof typeof MessagesStreamFallbackModes];
|
|
32
36
|
export interface GroupOptions {
|
|
33
37
|
sessionTimeout?: number;
|
|
34
38
|
rebalanceTimeout?: number;
|
|
@@ -46,9 +50,10 @@ export interface ConsumeBaseOptions<Key, Value, HeaderKey, HeaderValue> {
|
|
|
46
50
|
}
|
|
47
51
|
export interface StreamOptions {
|
|
48
52
|
topics: string[];
|
|
49
|
-
mode?:
|
|
50
|
-
fallbackMode?:
|
|
53
|
+
mode?: MessagesStreamModeValue;
|
|
54
|
+
fallbackMode?: MessagesStreamFallbackModeValue;
|
|
51
55
|
offsets?: TopicWithPartitionAndOffset[];
|
|
56
|
+
onCorruptedMessage?: CorruptedMessageHandler;
|
|
52
57
|
}
|
|
53
58
|
export type ConsumeOptions<Key, Value, HeaderKey, HeaderValue> = StreamOptions & ConsumeBaseOptions<Key, Value, HeaderKey, HeaderValue> & GroupOptions;
|
|
54
59
|
export type ConsumerOptions<Key, Value, HeaderKey, HeaderValue> = BaseOptions & {
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { ProduceAcks } from "../../apis/enumerations.js";
|
|
2
|
-
import {
|
|
3
|
-
import { api as produceV11 } from "../../apis/producer/produce.js";
|
|
2
|
+
import { createDiagnosticContext, producerInitIdempotentChannel, producerSendsChannel } from "../../diagnostic.js";
|
|
4
3
|
import { UserError } from "../../errors.js";
|
|
5
4
|
import { murmur2 } from "../../protocol/murmur2.js";
|
|
6
5
|
import { NumericMap } from "../../utils.js";
|
|
7
|
-
import { Base, kBootstrapBrokers, kCheckNotClosed, kClearMetadata, kClosed, kConnections, kMetadata, kOptions, kPerformDeduplicated, kPerformWithRetry, kPrometheus, kValidateOptions } from "../base/base.js";
|
|
6
|
+
import { Base, kAfterCreate, kBootstrapBrokers, kCheckNotClosed, kClearMetadata, kClosed, kConnections, kGetApi, kMetadata, kOptions, kPerformDeduplicated, kPerformWithRetry, kPrometheus, kValidateOptions } from "../base/base.js";
|
|
8
7
|
import { createPromisifiedCallback, kCallbackPromise, runConcurrentCallbacks } from "../callbacks.js";
|
|
9
8
|
import { ensureMetric } from "../metrics.js";
|
|
10
9
|
import { produceOptionsValidator, producerOptionsValidator, sendOptionsValidator } from "./options.js";
|
|
@@ -30,6 +29,9 @@ export class Producer extends Base {
|
|
|
30
29
|
options.acks = ProduceAcks.ALL;
|
|
31
30
|
options.retries = Number.MAX_SAFE_INTEGER;
|
|
32
31
|
}
|
|
32
|
+
else {
|
|
33
|
+
options.idempotent = false;
|
|
34
|
+
}
|
|
33
35
|
options.repeatOnStaleMetadata ??= true;
|
|
34
36
|
super(options);
|
|
35
37
|
this.#partitionsRoundRobin = new NumericMap();
|
|
@@ -43,6 +45,7 @@ export class Producer extends Base {
|
|
|
43
45
|
ensureMetric(this[kPrometheus], 'Gauge', 'kafka_producers', 'Number of active Kafka producers').inc();
|
|
44
46
|
this.#metricsProducedMessages = ensureMetric(this[kPrometheus], 'Counter', 'kafka_produced_messages', 'Number of produced Kafka messages');
|
|
45
47
|
}
|
|
48
|
+
this[kAfterCreate]('producer');
|
|
46
49
|
}
|
|
47
50
|
get producerId() {
|
|
48
51
|
return this.#producerInfo?.producerId;
|
|
@@ -84,18 +87,43 @@ export class Producer extends Base {
|
|
|
84
87
|
callback(validationError, undefined);
|
|
85
88
|
return callback[kCallbackPromise];
|
|
86
89
|
}
|
|
87
|
-
|
|
90
|
+
producerInitIdempotentChannel.traceCallback(this.#initIdempotentProducer, 1, createDiagnosticContext({ client: this, operation: 'initIdempotentProducer', options }), this, options, callback);
|
|
91
|
+
return callback[kCallbackPromise];
|
|
92
|
+
}
|
|
93
|
+
send(options, callback) {
|
|
94
|
+
if (!callback) {
|
|
95
|
+
callback = createPromisifiedCallback();
|
|
96
|
+
}
|
|
97
|
+
if (this[kCheckNotClosed](callback)) {
|
|
98
|
+
return callback[kCallbackPromise];
|
|
99
|
+
}
|
|
100
|
+
const validationError = this[kValidateOptions](options, sendOptionsValidator, '/options', false);
|
|
101
|
+
if (validationError) {
|
|
102
|
+
callback(validationError, undefined);
|
|
103
|
+
return callback[kCallbackPromise];
|
|
104
|
+
}
|
|
105
|
+
producerSendsChannel.traceCallback(this.#send, 1, createDiagnosticContext({ client: this, operation: 'send', options }), this, options, callback);
|
|
106
|
+
return callback[kCallbackPromise];
|
|
107
|
+
}
|
|
108
|
+
#initIdempotentProducer(options, callback) {
|
|
109
|
+
this[kPerformDeduplicated]('initProducerId', deduplicateCallback => {
|
|
88
110
|
this[kPerformWithRetry]('initProducerId', retryCallback => {
|
|
89
111
|
this[kConnections].getFirstAvailable(this[kBootstrapBrokers], (error, connection) => {
|
|
90
112
|
if (error) {
|
|
91
|
-
|
|
113
|
+
retryCallback(error, undefined);
|
|
92
114
|
return;
|
|
93
115
|
}
|
|
94
|
-
|
|
116
|
+
this[kGetApi]('InitProducerId', (error, api) => {
|
|
117
|
+
if (error) {
|
|
118
|
+
retryCallback(error, undefined);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
api(connection, null, this[kOptions].timeout, options.producerId ?? this[kOptions].producerId ?? 0n, options.producerEpoch ?? this[kOptions].producerEpoch ?? 0, retryCallback);
|
|
122
|
+
});
|
|
95
123
|
});
|
|
96
124
|
}, (error, response) => {
|
|
97
125
|
if (error) {
|
|
98
|
-
|
|
126
|
+
deduplicateCallback(error, undefined);
|
|
99
127
|
return;
|
|
100
128
|
}
|
|
101
129
|
this.#producerInfo = { producerId: response.producerId, producerEpoch: response.producerEpoch };
|
|
@@ -103,21 +131,9 @@ export class Producer extends Base {
|
|
|
103
131
|
}, 0);
|
|
104
132
|
}, callback);
|
|
105
133
|
}
|
|
106
|
-
send(options, callback) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
if (this[kCheckNotClosed](callback)) {
|
|
111
|
-
return callback[kCallbackPromise];
|
|
112
|
-
}
|
|
113
|
-
const validationError = this[kValidateOptions](options, sendOptionsValidator, '/options', false);
|
|
114
|
-
if (validationError) {
|
|
115
|
-
callback(validationError, undefined);
|
|
116
|
-
return callback[kCallbackPromise];
|
|
117
|
-
}
|
|
118
|
-
options.idempotent ??= this[kOptions].idempotent ?? false;
|
|
119
|
-
/* c8 ignore next */
|
|
120
|
-
options.repeatOnStaleMetadata ??= this[kOptions].repeatOnStaleMetadata ?? true;
|
|
134
|
+
#send(options, callback) {
|
|
135
|
+
options.idempotent ??= this[kOptions].idempotent;
|
|
136
|
+
options.repeatOnStaleMetadata ??= this[kOptions].repeatOnStaleMetadata;
|
|
121
137
|
options.partitioner ??= this[kOptions].partitioner;
|
|
122
138
|
const { idempotent, partitioner } = options;
|
|
123
139
|
if (idempotent) {
|
|
@@ -135,17 +151,17 @@ export class Producer extends Base {
|
|
|
135
151
|
callback(error, undefined);
|
|
136
152
|
return;
|
|
137
153
|
}
|
|
138
|
-
this
|
|
154
|
+
this.#send(options, callback);
|
|
139
155
|
});
|
|
140
|
-
return
|
|
156
|
+
return;
|
|
141
157
|
}
|
|
142
158
|
if (typeof options.producerId !== 'undefined' || typeof options.producerEpoch !== 'undefined') {
|
|
143
159
|
callback(new UserError('Cannot specify producerId or producerEpoch when using idempotent producer.'), undefined);
|
|
144
|
-
return
|
|
160
|
+
return;
|
|
145
161
|
}
|
|
146
162
|
if (options.acks !== ProduceAcks.ALL) {
|
|
147
163
|
callback(new UserError('Idempotent producer requires acks to be ALL (-1).'), undefined);
|
|
148
|
-
return
|
|
164
|
+
return;
|
|
149
165
|
}
|
|
150
166
|
}
|
|
151
167
|
const produceOptions = {
|
|
@@ -199,7 +215,6 @@ export class Producer extends Base {
|
|
|
199
215
|
});
|
|
200
216
|
}
|
|
201
217
|
this.#performSend(Array.from(topics), messages, options, produceOptions, callback);
|
|
202
|
-
return callback[kCallbackPromise];
|
|
203
218
|
}
|
|
204
219
|
#performSend(topics, messages, sendOptions, produceOptions, callback) {
|
|
205
220
|
// Get the metadata with the topic/partitions informations
|
|
@@ -282,7 +297,13 @@ export class Producer extends Base {
|
|
|
282
297
|
retryCallback(error, undefined);
|
|
283
298
|
return;
|
|
284
299
|
}
|
|
285
|
-
|
|
300
|
+
this[kGetApi]('Produce', (error, api) => {
|
|
301
|
+
if (error) {
|
|
302
|
+
retryCallback(error, undefined);
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
api(connection, acks, timeout, messages, produceOptions, retryCallback);
|
|
306
|
+
});
|
|
286
307
|
});
|
|
287
308
|
}, (error, results) => {
|
|
288
309
|
if (error) {
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type TracingChannel } from 'node:diagnostics_channel';
|
|
2
|
+
import { type Base } from './clients/base/base.ts';
|
|
3
|
+
import { type ConnectionPool } from './network/connection-pool.ts';
|
|
4
|
+
import { type Connection } from './network/connection.ts';
|
|
5
|
+
export type ClientType = 'base' | 'producer' | 'consumer' | 'admin';
|
|
6
|
+
export interface CreationEvent<InstanceType> {
|
|
7
|
+
type: ClientType | 'connection' | 'connectionPool';
|
|
8
|
+
instance: InstanceType;
|
|
9
|
+
}
|
|
10
|
+
export type ConnectionDiagnosticEvent<Attributes = Record<string, unknown>> = {
|
|
11
|
+
connection: Connection;
|
|
12
|
+
} & Attributes;
|
|
13
|
+
export type ConnectionPoolDiagnosticEvent<Attributes = Record<string, unknown>> = {
|
|
14
|
+
connectionPool: ConnectionPool;
|
|
15
|
+
} & Attributes;
|
|
16
|
+
export type ClientDiagnosticEvent<InstanceType extends Base = Base, Attributes = Record<string, unknown>> = {
|
|
17
|
+
client: InstanceType;
|
|
18
|
+
} & Attributes;
|
|
19
|
+
export type TracingChannelWithName<EventType extends object> = TracingChannel<string, EventType> & {
|
|
20
|
+
name: string;
|
|
21
|
+
};
|
|
22
|
+
export type DiagnosticContext<BaseContext> = BaseContext & {
|
|
23
|
+
operationId: bigint;
|
|
24
|
+
result?: unknown;
|
|
25
|
+
error?: unknown;
|
|
26
|
+
};
|
|
27
|
+
export declare const channelsNamespace: "plt:kafka";
|
|
28
|
+
export declare function createDiagnosticContext<BaseContext>(context: BaseContext): DiagnosticContext<BaseContext>;
|
|
29
|
+
export declare function notifyCreation<InstanceType>(type: ClientType | 'connection' | 'connection-pool' | 'messages-stream', instance: InstanceType): void;
|
|
30
|
+
export declare function createTracingChannel<DiagnosticEvent extends object>(name: string): TracingChannelWithName<DiagnosticEvent>;
|
|
31
|
+
export declare const instancesChannel: import("diagnostics_channel").Channel<unknown, unknown>;
|
|
32
|
+
export declare const connectionsConnectsChannel: TracingChannelWithName<ConnectionDiagnosticEvent<Record<string, unknown>>>;
|
|
33
|
+
export declare const connectionsApiChannel: TracingChannelWithName<ConnectionDiagnosticEvent<Record<string, unknown>>>;
|
|
34
|
+
export declare const connectionsPoolGetsChannel: TracingChannelWithName<ConnectionPoolDiagnosticEvent<Record<string, unknown>>>;
|
|
35
|
+
export declare const baseApisChannel: TracingChannelWithName<ClientDiagnosticEvent<Base<import("./index.ts").BaseOptions>, Record<string, unknown>>>;
|
|
36
|
+
export declare const baseMetadataChannel: TracingChannelWithName<ClientDiagnosticEvent<Base<import("./index.ts").BaseOptions>, Record<string, unknown>>>;
|
|
37
|
+
export declare const adminTopicsChannel: TracingChannelWithName<ClientDiagnosticEvent<Base<import("./index.ts").BaseOptions>, Record<string, unknown>>>;
|
|
38
|
+
export declare const adminGroupsChannel: TracingChannelWithName<ClientDiagnosticEvent<Base<import("./index.ts").BaseOptions>, Record<string, unknown>>>;
|
|
39
|
+
export declare const producerInitIdempotentChannel: TracingChannelWithName<ClientDiagnosticEvent<Base<import("./index.ts").BaseOptions>, Record<string, unknown>>>;
|
|
40
|
+
export declare const producerSendsChannel: TracingChannelWithName<ClientDiagnosticEvent<Base<import("./index.ts").BaseOptions>, Record<string, unknown>>>;
|
|
41
|
+
export declare const consumerGroupChannel: TracingChannelWithName<ClientDiagnosticEvent<Base<import("./index.ts").BaseOptions>, Record<string, unknown>>>;
|
|
42
|
+
export declare const consumerHeartbeatChannel: TracingChannelWithName<ClientDiagnosticEvent<Base<import("./index.ts").BaseOptions>, Record<string, unknown>>>;
|
|
43
|
+
export declare const consumerReceivesChannel: TracingChannelWithName<ClientDiagnosticEvent<Base<import("./index.ts").BaseOptions>, Record<string, unknown>>>;
|
|
44
|
+
export declare const consumerFetchesChannel: TracingChannelWithName<ClientDiagnosticEvent<Base<import("./index.ts").BaseOptions>, Record<string, unknown>>>;
|
|
45
|
+
export declare const consumerConsumesChannel: TracingChannelWithName<ClientDiagnosticEvent<Base<import("./index.ts").BaseOptions>, Record<string, unknown>>>;
|
|
46
|
+
export declare const consumerCommitsChannel: TracingChannelWithName<ClientDiagnosticEvent<Base<import("./index.ts").BaseOptions>, Record<string, unknown>>>;
|
|
47
|
+
export declare const consumerOffsetsChannel: TracingChannelWithName<ClientDiagnosticEvent<Base<import("./index.ts").BaseOptions>, Record<string, unknown>>>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { channel, tracingChannel } from 'node:diagnostics_channel';
|
|
2
|
+
export const channelsNamespace = 'plt:kafka';
|
|
3
|
+
let operationId = 0n;
|
|
4
|
+
export function createDiagnosticContext(context) {
|
|
5
|
+
return { operationId: operationId++, ...context };
|
|
6
|
+
}
|
|
7
|
+
export function notifyCreation(type, instance) {
|
|
8
|
+
instancesChannel.publish({ type, instance });
|
|
9
|
+
}
|
|
10
|
+
export function createTracingChannel(name) {
|
|
11
|
+
name = `${channelsNamespace}:${name}`;
|
|
12
|
+
const channel = tracingChannel(name);
|
|
13
|
+
channel.name = name;
|
|
14
|
+
return channel;
|
|
15
|
+
}
|
|
16
|
+
// Generic channel for objects creation
|
|
17
|
+
export const instancesChannel = channel(`${channelsNamespace}:instances`);
|
|
18
|
+
// Connection related channels
|
|
19
|
+
export const connectionsConnectsChannel = createTracingChannel('connections:connects');
|
|
20
|
+
export const connectionsApiChannel = createTracingChannel('connections:api');
|
|
21
|
+
export const connectionsPoolGetsChannel = createTracingChannel('connections:pool:get');
|
|
22
|
+
// Base channels
|
|
23
|
+
export const baseApisChannel = createTracingChannel('base:apis');
|
|
24
|
+
export const baseMetadataChannel = createTracingChannel('base:metadata');
|
|
25
|
+
// Admin channels
|
|
26
|
+
export const adminTopicsChannel = createTracingChannel('admin:topics');
|
|
27
|
+
export const adminGroupsChannel = createTracingChannel('admin:groups');
|
|
28
|
+
// Producer channels
|
|
29
|
+
export const producerInitIdempotentChannel = createTracingChannel('producer:initIdempotent');
|
|
30
|
+
export const producerSendsChannel = createTracingChannel('producer:sends');
|
|
31
|
+
// Consumer channels
|
|
32
|
+
export const consumerGroupChannel = createTracingChannel('consumer:group');
|
|
33
|
+
export const consumerHeartbeatChannel = createTracingChannel('consumer:heartbeat');
|
|
34
|
+
export const consumerReceivesChannel = createTracingChannel('consumer:receives');
|
|
35
|
+
export const consumerFetchesChannel = createTracingChannel('consumer:fetches');
|
|
36
|
+
export const consumerConsumesChannel = createTracingChannel('consumer:consumes');
|
|
37
|
+
export const consumerCommitsChannel = createTracingChannel('consumer:commits');
|
|
38
|
+
export const consumerOffsetsChannel = createTracingChannel('consumer:offsets');
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
declare const kGenericError: unique symbol;
|
|
2
2
|
declare const kMultipleErrors: unique symbol;
|
|
3
3
|
export declare const ERROR_PREFIX = "PLT_KFK_";
|
|
4
|
-
export declare const errorCodes: readonly ["PLT_KFK_AUTHENTICATION", "PLT_KFK_MULTIPLE", "PLT_KFK_NETWORK", "PLT_KFK_PROTOCOL", "PLT_KFK_RESPONSE", "PLT_KFK_TIMEOUT", "PLT_KFK_UNEXPECTED_CORRELATION_ID", "PLT_KFK_UNFINISHED_WRITE_BUFFER", "PLT_KFK_UNSUPPORTED_COMPRESSION", "PLT_KFK_UNSUPPORTED", "PLT_KFK_USER"];
|
|
4
|
+
export declare const errorCodes: readonly ["PLT_KFK_AUTHENTICATION", "PLT_KFK_MULTIPLE", "PLT_KFK_NETWORK", "PLT_KFK_PROTOCOL", "PLT_KFK_RESPONSE", "PLT_KFK_TIMEOUT", "PLT_KFK_UNEXPECTED_CORRELATION_ID", "PLT_KFK_UNFINISHED_WRITE_BUFFER", "PLT_KFK_UNSUPPORTED_API", "PLT_KFK_UNSUPPORTED_COMPRESSION", "PLT_KFK_UNSUPPORTED", "PLT_KFK_USER"];
|
|
5
5
|
export type ErrorCode = (typeof errorCodes)[number];
|
|
6
6
|
export type ErrorProperties = {
|
|
7
7
|
cause?: Error;
|
|
@@ -53,6 +53,10 @@ export declare class UnfinishedWriteBufferError extends GenericError {
|
|
|
53
53
|
static code: ErrorCode;
|
|
54
54
|
constructor(message: string, properties?: ErrorProperties);
|
|
55
55
|
}
|
|
56
|
+
export declare class UnsupportedApiError extends GenericError {
|
|
57
|
+
static code: ErrorCode;
|
|
58
|
+
constructor(message: string, properties?: ErrorProperties);
|
|
59
|
+
}
|
|
56
60
|
export declare class UnsupportedCompressionError extends GenericError {
|
|
57
61
|
static code: ErrorCode;
|
|
58
62
|
constructor(message: string, properties?: ErrorProperties);
|