wsp-ms-core 1.1.28 → 1.1.30
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/index.cjs +59 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +59 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -649,7 +649,9 @@ declare class KafkaManager extends EventManager {
|
|
|
649
649
|
private readonly groupId;
|
|
650
650
|
private leaderSelectionPromise;
|
|
651
651
|
private producerConnected;
|
|
652
|
+
private producerConnectPromise;
|
|
652
653
|
private isRecoveringLeader;
|
|
654
|
+
private readonly hasExplicitGroupId;
|
|
653
655
|
constructor(connection: EventManagerConnection);
|
|
654
656
|
private ensureProducerConnected;
|
|
655
657
|
private initializeKafkaClients;
|
|
@@ -664,6 +666,7 @@ declare class KafkaManager extends EventManager {
|
|
|
664
666
|
private logConsumerEvent;
|
|
665
667
|
private handleKafkaError;
|
|
666
668
|
private commitMessage;
|
|
669
|
+
private startHeartbeatLoop;
|
|
667
670
|
private run;
|
|
668
671
|
send(e: EventMessage): Promise<void>;
|
|
669
672
|
start(autocommit?: boolean): Promise<void>;
|
package/dist/index.d.ts
CHANGED
|
@@ -649,7 +649,9 @@ declare class KafkaManager extends EventManager {
|
|
|
649
649
|
private readonly groupId;
|
|
650
650
|
private leaderSelectionPromise;
|
|
651
651
|
private producerConnected;
|
|
652
|
+
private producerConnectPromise;
|
|
652
653
|
private isRecoveringLeader;
|
|
654
|
+
private readonly hasExplicitGroupId;
|
|
653
655
|
constructor(connection: EventManagerConnection);
|
|
654
656
|
private ensureProducerConnected;
|
|
655
657
|
private initializeKafkaClients;
|
|
@@ -664,6 +666,7 @@ declare class KafkaManager extends EventManager {
|
|
|
664
666
|
private logConsumerEvent;
|
|
665
667
|
private handleKafkaError;
|
|
666
668
|
private commitMessage;
|
|
669
|
+
private startHeartbeatLoop;
|
|
667
670
|
private run;
|
|
668
671
|
send(e: EventMessage): Promise<void>;
|
|
669
672
|
start(autocommit?: boolean): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -1731,18 +1731,44 @@ var KafkaManager = class extends EventManager {
|
|
|
1731
1731
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1732
1732
|
this.runtimeProcess = globalThis?.process;
|
|
1733
1733
|
this.producerConnected = false;
|
|
1734
|
+
this.producerConnectPromise = null;
|
|
1734
1735
|
this.isRecoveringLeader = false;
|
|
1735
1736
|
this.seedBrokers = this.resolveBrokerList(this._connection.brokers ?? []);
|
|
1736
|
-
|
|
1737
|
+
const envGroupId = this.runtimeProcess?.env?.KAFKA_GROUP;
|
|
1738
|
+
this.hasExplicitGroupId = Boolean(envGroupId);
|
|
1739
|
+
this.groupId = envGroupId || "__missing-kafka-group__";
|
|
1740
|
+
if (!this.hasExplicitGroupId) {
|
|
1741
|
+
console.warn("[KafkaManager] KAFKA_GROUP is not set. Producing is allowed, but consuming will fail until a unique group id is configured.");
|
|
1742
|
+
}
|
|
1737
1743
|
this.initializeKafkaClients(this.seedBrokers);
|
|
1738
1744
|
this.leaderSelectionPromise = this.pinToLeaderBroker();
|
|
1739
1745
|
}
|
|
1746
|
+
// La conexión se comparte entre sends concurrentes vía un latch: sin él, dos send() en paralelo
|
|
1747
|
+
// dispararían dos connect() simultáneos sobre el mismo producer. El producer queda conectado
|
|
1748
|
+
// entre sends (kafkajs está diseñado para conexiones long-lived); solo stop() lo desconecta.
|
|
1749
|
+
// Los guards `this.producer === producer` protegen contra initializeKafkaClients() reemplazando
|
|
1750
|
+
// el producer a mitad de un connect (recovery de líder): sin ellos, el latch viejo marcaría como
|
|
1751
|
+
// conectado al producer nuevo sin estarlo, y todos los sends siguientes fallarían.
|
|
1740
1752
|
async ensureProducerConnected() {
|
|
1741
1753
|
await this.waitForLeaderSelection();
|
|
1742
1754
|
if (this.producerConnected)
|
|
1743
1755
|
return;
|
|
1744
|
-
|
|
1745
|
-
|
|
1756
|
+
if (!this.producerConnectPromise) {
|
|
1757
|
+
const producer = this.producer;
|
|
1758
|
+
this.producerConnectPromise = producer.connect().then(() => {
|
|
1759
|
+
if (this.producer === producer) {
|
|
1760
|
+
this.producerConnected = true;
|
|
1761
|
+
}
|
|
1762
|
+
}).finally(() => {
|
|
1763
|
+
if (this.producer === producer) {
|
|
1764
|
+
this.producerConnectPromise = null;
|
|
1765
|
+
}
|
|
1766
|
+
});
|
|
1767
|
+
}
|
|
1768
|
+
await this.producerConnectPromise;
|
|
1769
|
+
if (!this.producerConnected) {
|
|
1770
|
+
return this.ensureProducerConnected();
|
|
1771
|
+
}
|
|
1746
1772
|
}
|
|
1747
1773
|
initializeKafkaClients(brokers) {
|
|
1748
1774
|
this.kafka = new Kafka({
|
|
@@ -1759,6 +1785,7 @@ var KafkaManager = class extends EventManager {
|
|
|
1759
1785
|
this.producer = this.kafka.producer();
|
|
1760
1786
|
this.brokers = brokers;
|
|
1761
1787
|
this.producerConnected = false;
|
|
1788
|
+
this.producerConnectPromise = null;
|
|
1762
1789
|
this.registerConsumerEventHandlers();
|
|
1763
1790
|
}
|
|
1764
1791
|
async pinToLeaderBroker() {
|
|
@@ -1949,7 +1976,22 @@ var KafkaManager = class extends EventManager {
|
|
|
1949
1976
|
const next = (BigInt(message.offset) + 1n).toString();
|
|
1950
1977
|
await this.consumer.commitOffsets([{ topic, partition, offset: next }]);
|
|
1951
1978
|
}
|
|
1979
|
+
// Mantiene viva la sesión del consumer mientras un handler tarda más que el sessionTimeout
|
|
1980
|
+
// (default 30s de kafkajs). Sin esto, un handler lento hace que el broker expulse al consumer
|
|
1981
|
+
// a mitad de procesamiento → rebalance → el mensaje se reentrega → loop. kafkajs ya throttlea
|
|
1982
|
+
// heartbeat() internamente al heartbeatInterval, así que llamarlo de más no tiene costo.
|
|
1983
|
+
startHeartbeatLoop(heartbeat) {
|
|
1984
|
+
const interval = setInterval(() => {
|
|
1985
|
+
heartbeat().catch((error) => {
|
|
1986
|
+
console.warn("[KafkaManager] Heartbeat failed during message processing", { error: error?.message ?? error });
|
|
1987
|
+
});
|
|
1988
|
+
}, 5e3);
|
|
1989
|
+
return () => clearInterval(interval);
|
|
1990
|
+
}
|
|
1952
1991
|
async run(autocommit = false) {
|
|
1992
|
+
if (!this.hasExplicitGroupId) {
|
|
1993
|
+
throw new InternalError(ErrorManager.APP_ERRORS.PROCESS, "KAFKA_GROUP env var is required to consume. Set a unique consumer group id per service.");
|
|
1994
|
+
}
|
|
1953
1995
|
const __run = async () => {
|
|
1954
1996
|
await this.waitForLeaderSelection();
|
|
1955
1997
|
await this.execCallback(this._onStart, { message: `--- ${this.constructor.name} started ---` });
|
|
@@ -1997,7 +2039,12 @@ var KafkaManager = class extends EventManager {
|
|
|
1997
2039
|
console.log("[KafkaManager] H - before execRoute", {
|
|
1998
2040
|
offset: message.offset
|
|
1999
2041
|
});
|
|
2000
|
-
|
|
2042
|
+
const stopHeartbeatLoop = this.startHeartbeatLoop(heartbeat);
|
|
2043
|
+
try {
|
|
2044
|
+
await this.execRoute(topic, event);
|
|
2045
|
+
} finally {
|
|
2046
|
+
stopHeartbeatLoop();
|
|
2047
|
+
}
|
|
2001
2048
|
console.log("[KafkaManager] I - after execRoute", {
|
|
2002
2049
|
elapsedMs: Date.now() - execRouteStart
|
|
2003
2050
|
});
|
|
@@ -2065,8 +2112,6 @@ var KafkaManager = class extends EventManager {
|
|
|
2065
2112
|
}
|
|
2066
2113
|
]
|
|
2067
2114
|
});
|
|
2068
|
-
await this.producer.disconnect();
|
|
2069
|
-
this.producerConnected = false;
|
|
2070
2115
|
} catch (error) {
|
|
2071
2116
|
throw new InternalError(error.toString());
|
|
2072
2117
|
}
|
|
@@ -2083,6 +2128,9 @@ var KafkaManager = class extends EventManager {
|
|
|
2083
2128
|
async stop() {
|
|
2084
2129
|
await this.consumer.stop();
|
|
2085
2130
|
await this.consumer.disconnect();
|
|
2131
|
+
if (this.producerConnectPromise) {
|
|
2132
|
+
await this.producerConnectPromise.catch(() => void 0);
|
|
2133
|
+
}
|
|
2086
2134
|
if (this.producerConnected) {
|
|
2087
2135
|
await this.producer.disconnect();
|
|
2088
2136
|
this.producerConnected = false;
|
|
@@ -2113,7 +2161,9 @@ var _MysqlConnector = class _MysqlConnector {
|
|
|
2113
2161
|
return rows;
|
|
2114
2162
|
}
|
|
2115
2163
|
async getConnection() {
|
|
2164
|
+
console.log("[MysqlConnector] BEFORE pool.getConnection");
|
|
2116
2165
|
const conn = await this._pool.getConnection();
|
|
2166
|
+
console.log("[MysqlConnector] AFTER pool.getConnection");
|
|
2117
2167
|
return this.wrap(conn);
|
|
2118
2168
|
}
|
|
2119
2169
|
async closePool() {
|
|
@@ -2292,6 +2342,7 @@ var DefaultMysqlInboxRunner = class {
|
|
|
2292
2342
|
}
|
|
2293
2343
|
async saveEvent(e, repository) {
|
|
2294
2344
|
try {
|
|
2345
|
+
console.log("[InboxRunner] BEFORE create inbox record");
|
|
2295
2346
|
let record = new InboxRecord(
|
|
2296
2347
|
UUID.create(),
|
|
2297
2348
|
e.tenant,
|
|
@@ -2300,7 +2351,9 @@ var DefaultMysqlInboxRunner = class {
|
|
|
2300
2351
|
JSON.stringify(e.message),
|
|
2301
2352
|
ProcessStatus.PENDING
|
|
2302
2353
|
);
|
|
2354
|
+
console.log("[InboxRunner] BEFORE repository.create");
|
|
2303
2355
|
await repository.create(record);
|
|
2356
|
+
console.log("[InboxRunner] AFTER repository.create");
|
|
2304
2357
|
} catch (error) {
|
|
2305
2358
|
throw error;
|
|
2306
2359
|
}
|