@514labs/moose-lib 0.6.276-ci-6-g278c5539 → 0.6.276-ci-1-gfe86cd2c
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/browserCompatible.js +57 -1
- package/dist/browserCompatible.js.map +1 -1
- package/dist/browserCompatible.mjs +62 -2
- package/dist/browserCompatible.mjs.map +1 -1
- package/dist/compilerPlugin.js.map +1 -1
- package/dist/compilerPlugin.mjs +5 -1
- package/dist/compilerPlugin.mjs.map +1 -1
- package/dist/dmv2/index.js +57 -1
- package/dist/dmv2/index.js.map +1 -1
- package/dist/dmv2/index.mjs +62 -2
- package/dist/dmv2/index.mjs.map +1 -1
- package/dist/index.d.mts +27 -2
- package/dist/index.d.ts +27 -2
- package/dist/index.js +63 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +65 -2
- package/dist/index.mjs.map +1 -1
- package/dist/moose-runner.js +191 -75
- package/dist/moose-runner.js.map +1 -1
- package/dist/moose-runner.mjs +197 -77
- package/dist/moose-runner.mjs.map +1 -1
- package/package.json +1 -1
package/dist/moose-runner.js
CHANGED
|
@@ -55,7 +55,7 @@ function createProducerConfig(maxMessageBytes) {
|
|
|
55
55
|
...maxMessageBytes && { "message.max.bytes": maxMessageBytes }
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
|
-
var import_http, import_client, import_kafka_javascript, Kafka, compilerLog, getClickhouseClient, cliLog, MAX_RETRIES, MAX_RETRY_TIME_MS, RETRY_INITIAL_TIME_MS, MAX_RETRIES_PRODUCER, ACKs, parseBrokerString, logError, buildSaslConfig, getKafkaClient;
|
|
58
|
+
var import_http, import_client, import_kafka_javascript, Kafka, compilerLog, getClickhouseClient, cliLog, MAX_RETRIES, MAX_RETRY_TIME_MS, RETRY_INITIAL_TIME_MS, MAX_RETRIES_PRODUCER, ACKs, parseBrokerString, logError, buildSaslConfig, getKafkaClient, buildNativeSaslConfig, createNativeKafkaConsumer;
|
|
59
59
|
var init_commons = __esm({
|
|
60
60
|
"src/commons.ts"() {
|
|
61
61
|
"use strict";
|
|
@@ -152,6 +152,59 @@ var init_commons = __esm({
|
|
|
152
152
|
}
|
|
153
153
|
});
|
|
154
154
|
};
|
|
155
|
+
buildNativeSaslConfig = (logger2, cfg) => {
|
|
156
|
+
if (!cfg.saslMechanism || !cfg.saslUsername || !cfg.saslPassword) {
|
|
157
|
+
return {};
|
|
158
|
+
}
|
|
159
|
+
const mechanism = cfg.saslMechanism.toUpperCase();
|
|
160
|
+
const validMechanisms = ["PLAIN", "SCRAM-SHA-256", "SCRAM-SHA-512"];
|
|
161
|
+
if (!validMechanisms.includes(mechanism)) {
|
|
162
|
+
logger2.warn(`Unsupported SASL mechanism: ${cfg.saslMechanism}`);
|
|
163
|
+
return {};
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
"sasl.mechanisms": mechanism,
|
|
167
|
+
"sasl.username": cfg.saslUsername,
|
|
168
|
+
"sasl.password": cfg.saslPassword
|
|
169
|
+
};
|
|
170
|
+
};
|
|
171
|
+
createNativeKafkaConsumer = (cfg, logger2, rebalanceCb) => {
|
|
172
|
+
const brokers = parseBrokerString(cfg.broker || "");
|
|
173
|
+
if (brokers.length === 0) {
|
|
174
|
+
throw new Error(`No valid broker addresses found in: "${cfg.broker}"`);
|
|
175
|
+
}
|
|
176
|
+
logger2.log(
|
|
177
|
+
`Creating native KafkaConsumer with brokers: ${brokers.join(", ")}`
|
|
178
|
+
);
|
|
179
|
+
logger2.log(`Security protocol: ${cfg.securityProtocol || "plaintext"}`);
|
|
180
|
+
logger2.log(`Client ID: ${cfg.clientId}`);
|
|
181
|
+
logger2.log(`Group ID: ${cfg.groupId}`);
|
|
182
|
+
const saslConfig = buildNativeSaslConfig(logger2, cfg);
|
|
183
|
+
const consumerConfig = {
|
|
184
|
+
// Connection
|
|
185
|
+
"bootstrap.servers": brokers.join(","),
|
|
186
|
+
"client.id": cfg.clientId,
|
|
187
|
+
// Group management
|
|
188
|
+
"group.id": cfg.groupId,
|
|
189
|
+
"session.timeout.ms": cfg.sessionTimeoutMs ?? 3e4,
|
|
190
|
+
"heartbeat.interval.ms": cfg.heartbeatIntervalMs ?? 3e3,
|
|
191
|
+
"max.poll.interval.ms": cfg.maxPollIntervalMs ?? 3e5,
|
|
192
|
+
// Offset management
|
|
193
|
+
"enable.auto.commit": cfg.autoCommit ?? true,
|
|
194
|
+
"auto.commit.interval.ms": cfg.autoCommitIntervalMs ?? 5e3,
|
|
195
|
+
// Security
|
|
196
|
+
...cfg.securityProtocol === "SASL_SSL" && {
|
|
197
|
+
"security.protocol": "sasl_ssl"
|
|
198
|
+
},
|
|
199
|
+
...saslConfig,
|
|
200
|
+
// Rebalance callback
|
|
201
|
+
...rebalanceCb && { rebalance_cb: rebalanceCb }
|
|
202
|
+
};
|
|
203
|
+
const topicConfig = {
|
|
204
|
+
"auto.offset.reset": cfg.autoOffsetReset ?? "earliest"
|
|
205
|
+
};
|
|
206
|
+
return new import_kafka_javascript.KafkaConsumer(consumerConfig, topicConfig);
|
|
207
|
+
};
|
|
155
208
|
}
|
|
156
209
|
});
|
|
157
210
|
|
|
@@ -1879,8 +1932,6 @@ init_commons();
|
|
|
1879
1932
|
var { Kafka: Kafka2 } = import_kafka_javascript2.KafkaJS;
|
|
1880
1933
|
var HOSTNAME = process3.env.HOSTNAME;
|
|
1881
1934
|
var AUTO_COMMIT_INTERVAL_MS = 5e3;
|
|
1882
|
-
var PARTITIONS_CONSUMED_CONCURRENTLY = 3;
|
|
1883
|
-
var MAX_RETRIES_CONSUMER = 150;
|
|
1884
1935
|
var SESSION_TIMEOUT_CONSUMER = 3e4;
|
|
1885
1936
|
var HEARTBEAT_INTERVAL_CONSUMER = 3e3;
|
|
1886
1937
|
var DEFAULT_MAX_STREAMING_CONCURRENCY = 100;
|
|
@@ -1921,23 +1972,31 @@ var stopProducer = async (logger2, producer) => {
|
|
|
1921
1972
|
var stopConsumer = async (logger2, consumer, sourceTopic) => {
|
|
1922
1973
|
try {
|
|
1923
1974
|
logger2.log("Pausing consumer...");
|
|
1924
|
-
const
|
|
1975
|
+
const topicPartitions = Array.from(
|
|
1925
1976
|
{ length: sourceTopic.partitions },
|
|
1926
|
-
(_, i) =>
|
|
1927
|
-
);
|
|
1928
|
-
await consumer.pause([
|
|
1929
|
-
{
|
|
1977
|
+
(_, i) => ({
|
|
1930
1978
|
topic: sourceTopic.name,
|
|
1931
|
-
|
|
1932
|
-
}
|
|
1933
|
-
|
|
1979
|
+
partition: i
|
|
1980
|
+
})
|
|
1981
|
+
);
|
|
1982
|
+
consumer.pause(topicPartitions);
|
|
1934
1983
|
logger2.log("Disconnecting consumer...");
|
|
1935
|
-
await
|
|
1984
|
+
await new Promise((resolve2, reject) => {
|
|
1985
|
+
consumer.disconnect((err) => {
|
|
1986
|
+
if (err) {
|
|
1987
|
+
reject(err);
|
|
1988
|
+
} else {
|
|
1989
|
+
resolve2();
|
|
1990
|
+
}
|
|
1991
|
+
});
|
|
1992
|
+
});
|
|
1936
1993
|
logger2.log("Consumer is shutting down...");
|
|
1937
1994
|
} catch (error) {
|
|
1938
1995
|
logger2.error(`Error during consumer shutdown: ${error}`);
|
|
1939
1996
|
try {
|
|
1940
|
-
await
|
|
1997
|
+
await new Promise((resolve2) => {
|
|
1998
|
+
consumer.disconnect(() => resolve2());
|
|
1999
|
+
});
|
|
1941
2000
|
logger2.log("Consumer disconnected after error");
|
|
1942
2001
|
} catch (disconnectError) {
|
|
1943
2002
|
logger2.error(`Failed to disconnect consumer: ${disconnectError}`);
|
|
@@ -2177,7 +2236,15 @@ var startConsumer = async (args, logger2, metrics, _parallelism, consumer, produ
|
|
|
2177
2236
|
}
|
|
2178
2237
|
try {
|
|
2179
2238
|
logger2.log("Connecting consumer...");
|
|
2180
|
-
await
|
|
2239
|
+
await new Promise((resolve2, reject) => {
|
|
2240
|
+
consumer.connect({}, (err) => {
|
|
2241
|
+
if (err) {
|
|
2242
|
+
reject(err);
|
|
2243
|
+
} else {
|
|
2244
|
+
resolve2();
|
|
2245
|
+
}
|
|
2246
|
+
});
|
|
2247
|
+
});
|
|
2181
2248
|
logger2.log("Consumer connected successfully");
|
|
2182
2249
|
} catch (error) {
|
|
2183
2250
|
logger2.error("Failed to connect consumer:");
|
|
@@ -2202,61 +2269,94 @@ var startConsumer = async (args, logger2, metrics, _parallelism, consumer, produ
|
|
|
2202
2269
|
streamingFunctions = [[loadStreamingFunction(args.functionFilePath), {}]];
|
|
2203
2270
|
fieldMutations = void 0;
|
|
2204
2271
|
}
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2272
|
+
consumer.subscribe([args.sourceTopic.name]);
|
|
2273
|
+
consumer.setDefaultConsumeTimeout(1e3);
|
|
2274
|
+
let isRunning = true;
|
|
2275
|
+
const consumeLoop = async () => {
|
|
2276
|
+
while (isRunning && consumer.isConnected()) {
|
|
2277
|
+
try {
|
|
2278
|
+
const messages = await new Promise(
|
|
2279
|
+
(resolve2, reject) => {
|
|
2280
|
+
consumer.consume(CONSUMER_MAX_BATCH_SIZE, (err, messages2) => {
|
|
2281
|
+
if (err) {
|
|
2282
|
+
reject(err);
|
|
2283
|
+
} else {
|
|
2284
|
+
resolve2(messages2 || []);
|
|
2285
|
+
}
|
|
2286
|
+
});
|
|
2287
|
+
}
|
|
2288
|
+
);
|
|
2289
|
+
if (messages.length === 0) {
|
|
2290
|
+
continue;
|
|
2291
|
+
}
|
|
2292
|
+
metrics.count_in += messages.length;
|
|
2293
|
+
cliLog({
|
|
2294
|
+
action: "Received",
|
|
2295
|
+
message: `${logger2.logPrefix} ${messages.length} message(s)`
|
|
2296
|
+
});
|
|
2297
|
+
logger2.log(`Received ${messages.length} message(s)`);
|
|
2298
|
+
const readableStream = import_node_stream2.Readable.from(messages);
|
|
2299
|
+
const processedMessages = await readableStream.map(
|
|
2300
|
+
async (message) => {
|
|
2301
|
+
const kafkaMessage = {
|
|
2302
|
+
value: message.value,
|
|
2303
|
+
key: message.key,
|
|
2304
|
+
partition: message.partition,
|
|
2305
|
+
offset: message.offset,
|
|
2306
|
+
timestamp: message.timestamp,
|
|
2307
|
+
headers: message.headers
|
|
2308
|
+
};
|
|
2309
|
+
return handleMessage(
|
|
2310
|
+
logger2,
|
|
2311
|
+
streamingFunctions,
|
|
2312
|
+
kafkaMessage,
|
|
2313
|
+
producer,
|
|
2314
|
+
fieldMutations
|
|
2315
|
+
);
|
|
2316
|
+
},
|
|
2317
|
+
{
|
|
2318
|
+
concurrency: MAX_STREAMING_CONCURRENCY
|
|
2231
2319
|
}
|
|
2232
|
-
|
|
2320
|
+
).toArray();
|
|
2321
|
+
const filteredMessages = processedMessages.flat().filter((msg) => msg !== void 0 && msg.value !== void 0);
|
|
2322
|
+
if (args.targetTopic === void 0 || processedMessages.length === 0) {
|
|
2323
|
+
continue;
|
|
2324
|
+
}
|
|
2325
|
+
if (filteredMessages.length > 0) {
|
|
2326
|
+
await sendMessages(
|
|
2233
2327
|
logger2,
|
|
2234
|
-
|
|
2235
|
-
|
|
2328
|
+
metrics,
|
|
2329
|
+
args.targetTopic,
|
|
2236
2330
|
producer,
|
|
2237
|
-
|
|
2331
|
+
filteredMessages
|
|
2238
2332
|
);
|
|
2239
|
-
},
|
|
2240
|
-
{
|
|
2241
|
-
concurrency: MAX_STREAMING_CONCURRENCY
|
|
2242
2333
|
}
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2334
|
+
} catch (error) {
|
|
2335
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
2336
|
+
const kafkaError = error;
|
|
2337
|
+
if (kafkaError.code === import_kafka_javascript2.CODES.ERRORS.ERR__TIMED_OUT) {
|
|
2338
|
+
continue;
|
|
2339
|
+
}
|
|
2340
|
+
if (kafkaError.code === import_kafka_javascript2.CODES.ERRORS.ERR__PARTITION_EOF) {
|
|
2341
|
+
continue;
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
logger2.error(`Error consuming messages: ${error}`);
|
|
2345
|
+
if (error instanceof Error) {
|
|
2346
|
+
logError(logger2, error);
|
|
2347
|
+
}
|
|
2348
|
+
await new Promise((resolve2) => setTimeout(resolve2, 100));
|
|
2257
2349
|
}
|
|
2258
2350
|
}
|
|
2351
|
+
};
|
|
2352
|
+
consumeLoop().catch((err) => {
|
|
2353
|
+
logger2.error(`Consumer loop crashed: ${err}`);
|
|
2354
|
+
isRunning = false;
|
|
2259
2355
|
});
|
|
2356
|
+
consumer._isRunning = isRunning;
|
|
2357
|
+
consumer._stopConsuming = () => {
|
|
2358
|
+
isRunning = false;
|
|
2359
|
+
};
|
|
2260
2360
|
logger2.log("Consumer is running...");
|
|
2261
2361
|
};
|
|
2262
2362
|
var buildLogger = (args, workerId) => {
|
|
@@ -2336,6 +2436,33 @@ var runStreamingFunctions = async (args) => {
|
|
|
2336
2436
|
setTimeout(() => sendMessageMetrics(logger2, metrics), 1e3);
|
|
2337
2437
|
const clientIdPrefix = HOSTNAME ? `${HOSTNAME}-` : "";
|
|
2338
2438
|
const processId = `${clientIdPrefix}${streamingFuncId}-ts-${worker.id}`;
|
|
2439
|
+
const consumer = createNativeKafkaConsumer(
|
|
2440
|
+
{
|
|
2441
|
+
clientId: processId,
|
|
2442
|
+
broker: args.broker,
|
|
2443
|
+
groupId: streamingFuncId,
|
|
2444
|
+
securityProtocol: args.securityProtocol,
|
|
2445
|
+
saslUsername: args.saslUsername,
|
|
2446
|
+
saslPassword: args.saslPassword,
|
|
2447
|
+
saslMechanism: args.saslMechanism,
|
|
2448
|
+
sessionTimeoutMs: SESSION_TIMEOUT_CONSUMER,
|
|
2449
|
+
heartbeatIntervalMs: HEARTBEAT_INTERVAL_CONSUMER,
|
|
2450
|
+
autoCommit: true,
|
|
2451
|
+
autoCommitIntervalMs: AUTO_COMMIT_INTERVAL_MS,
|
|
2452
|
+
autoOffsetReset: "earliest",
|
|
2453
|
+
maxBatchSize: CONSUMER_MAX_BATCH_SIZE
|
|
2454
|
+
},
|
|
2455
|
+
logger2,
|
|
2456
|
+
(err, assignments) => {
|
|
2457
|
+
if (err.code === import_kafka_javascript2.CODES.ERRORS.ERR__ASSIGN_PARTITIONS) {
|
|
2458
|
+
logger2.log(`Assigned partitions: ${JSON.stringify(assignments)}`);
|
|
2459
|
+
} else if (err.code === import_kafka_javascript2.CODES.ERRORS.ERR__REVOKE_PARTITIONS) {
|
|
2460
|
+
logger2.log(`Revoked partitions: ${JSON.stringify(assignments)}`);
|
|
2461
|
+
} else {
|
|
2462
|
+
logger2.error(`Rebalance error: ${err.message}`);
|
|
2463
|
+
}
|
|
2464
|
+
}
|
|
2465
|
+
);
|
|
2339
2466
|
const kafka = await getKafkaClient(
|
|
2340
2467
|
{
|
|
2341
2468
|
clientId: processId,
|
|
@@ -2347,20 +2474,6 @@ var runStreamingFunctions = async (args) => {
|
|
|
2347
2474
|
},
|
|
2348
2475
|
logger2
|
|
2349
2476
|
);
|
|
2350
|
-
const consumer = kafka.consumer({
|
|
2351
|
-
kafkaJS: {
|
|
2352
|
-
groupId: streamingFuncId,
|
|
2353
|
-
sessionTimeout: SESSION_TIMEOUT_CONSUMER,
|
|
2354
|
-
heartbeatInterval: HEARTBEAT_INTERVAL_CONSUMER,
|
|
2355
|
-
retry: {
|
|
2356
|
-
retries: MAX_RETRIES_CONSUMER
|
|
2357
|
-
},
|
|
2358
|
-
autoCommit: true,
|
|
2359
|
-
autoCommitInterval: AUTO_COMMIT_INTERVAL_MS,
|
|
2360
|
-
fromBeginning: true
|
|
2361
|
-
},
|
|
2362
|
-
"js.consumer.max.batch.size": CONSUMER_MAX_BATCH_SIZE
|
|
2363
|
-
});
|
|
2364
2477
|
const maxMessageBytes = args.targetTopic?.max_message_bytes || 1024 * 1024;
|
|
2365
2478
|
const producer = kafka.producer(
|
|
2366
2479
|
createProducerConfig(maxMessageBytes)
|
|
@@ -2397,6 +2510,9 @@ var runStreamingFunctions = async (args) => {
|
|
|
2397
2510
|
},
|
|
2398
2511
|
workerStop: async ([logger2, producer, consumer]) => {
|
|
2399
2512
|
logger2.log(`Received SIGTERM, shutting down gracefully...`);
|
|
2513
|
+
if (consumer._stopConsuming) {
|
|
2514
|
+
consumer._stopConsuming();
|
|
2515
|
+
}
|
|
2400
2516
|
logger2.log("Stopping consumer first...");
|
|
2401
2517
|
await stopConsumer(logger2, consumer, args.sourceTopic);
|
|
2402
2518
|
logger2.log("Waiting for in-flight messages to complete...");
|