wsp-ms-core 1.1.22 → 1.1.24
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 +120 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +11 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +125 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1778,9 +1778,13 @@ var import_kafkajs = require("kafkajs");
|
|
|
1778
1778
|
var KafkaManager = class extends EventManager {
|
|
1779
1779
|
constructor(connection) {
|
|
1780
1780
|
super(connection);
|
|
1781
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1782
|
+
this.runtimeProcess = globalThis?.process;
|
|
1781
1783
|
this.producerConnected = false;
|
|
1784
|
+
this.exitingDueToLeaderError = false;
|
|
1785
|
+
this.brokers = this.resolveBrokerList(this._connection.brokers ?? []);
|
|
1782
1786
|
this.kafka = new import_kafkajs.Kafka({
|
|
1783
|
-
brokers: this.
|
|
1787
|
+
brokers: this.brokers,
|
|
1784
1788
|
ssl: true,
|
|
1785
1789
|
sasl: {
|
|
1786
1790
|
mechanism: "scram-sha-256",
|
|
@@ -1789,8 +1793,10 @@ var KafkaManager = class extends EventManager {
|
|
|
1789
1793
|
},
|
|
1790
1794
|
logLevel: import_kafkajs.logLevel.ERROR
|
|
1791
1795
|
});
|
|
1792
|
-
|
|
1796
|
+
const groupId = this.runtimeProcess?.env?.KAFKA_GROUP || "default";
|
|
1797
|
+
this.consumer = this.kafka.consumer({ groupId });
|
|
1793
1798
|
this.producer = this.kafka.producer();
|
|
1799
|
+
this.registerConsumerEventHandlers();
|
|
1794
1800
|
}
|
|
1795
1801
|
async ensureProducerConnected() {
|
|
1796
1802
|
if (this.producerConnected)
|
|
@@ -1798,6 +1804,107 @@ var KafkaManager = class extends EventManager {
|
|
|
1798
1804
|
await this.producer.connect();
|
|
1799
1805
|
this.producerConnected = true;
|
|
1800
1806
|
}
|
|
1807
|
+
resolveBrokerList(brokers) {
|
|
1808
|
+
const envBrokers = (this.runtimeProcess?.env?.KAFKA_BROKERS ?? "").split(",").map((value) => value.trim()).filter(Boolean);
|
|
1809
|
+
const normalized = [...brokers, ...envBrokers].map((value) => this.normalizeBroker(value)).filter((value) => Boolean(value));
|
|
1810
|
+
const uniqueBrokers = Array.from(new Set(normalized));
|
|
1811
|
+
if (!uniqueBrokers.length) {
|
|
1812
|
+
throw new InternalError(ErrorManager.APP_ERRORS.PROCESS, "Kafka brokers configuration is empty.");
|
|
1813
|
+
}
|
|
1814
|
+
console.info("[KafkaManager] Using brokers", uniqueBrokers);
|
|
1815
|
+
return uniqueBrokers;
|
|
1816
|
+
}
|
|
1817
|
+
normalizeBroker(broker) {
|
|
1818
|
+
if (!broker)
|
|
1819
|
+
return null;
|
|
1820
|
+
const trimmed = broker.trim();
|
|
1821
|
+
if (!trimmed)
|
|
1822
|
+
return null;
|
|
1823
|
+
if (trimmed.startsWith("PLAINTEXT://") || trimmed.startsWith("SSL://")) {
|
|
1824
|
+
return trimmed;
|
|
1825
|
+
}
|
|
1826
|
+
return trimmed.includes(":") ? trimmed : `${trimmed}:9092`;
|
|
1827
|
+
}
|
|
1828
|
+
registerConsumerEventHandlers() {
|
|
1829
|
+
const events = this.consumer.events;
|
|
1830
|
+
this.consumer.on(events.REBALANCING, async (event) => {
|
|
1831
|
+
await this.logConsumerEvent("REBALANCING", event);
|
|
1832
|
+
});
|
|
1833
|
+
const rebalancedEvent = this.consumer.events.REBALANCED;
|
|
1834
|
+
if (rebalancedEvent) {
|
|
1835
|
+
this.consumer.on(rebalancedEvent, async (event) => {
|
|
1836
|
+
await this.logConsumerEvent("REBALANCED", event);
|
|
1837
|
+
});
|
|
1838
|
+
}
|
|
1839
|
+
this.consumer.on(events.REQUEST_TIMEOUT, async (event) => {
|
|
1840
|
+
await this.logConsumerEvent("REQUEST_TIMEOUT", event, "error");
|
|
1841
|
+
this.handleKafkaError(event?.payload?.error, "consumer.REQUEST_TIMEOUT", { broker: event?.payload?.broker });
|
|
1842
|
+
});
|
|
1843
|
+
this.consumer.on(events.CRASH, async (event) => {
|
|
1844
|
+
await this.logConsumerEvent("CRASH", event, "error");
|
|
1845
|
+
this.handleKafkaError(event?.payload?.error, "consumer.CRASH", { broker: event?.payload?.broker });
|
|
1846
|
+
});
|
|
1847
|
+
this.consumer.on(events.DISCONNECT, async (event) => {
|
|
1848
|
+
await this.logConsumerEvent("DISCONNECT", event, "error");
|
|
1849
|
+
});
|
|
1850
|
+
this.consumer.on(events.CONNECT, async (event) => {
|
|
1851
|
+
await this.logConsumerEvent("CONNECT", event);
|
|
1852
|
+
});
|
|
1853
|
+
}
|
|
1854
|
+
async logConsumerEvent(eventName, kafkaEvent, level = "info") {
|
|
1855
|
+
const payload = kafkaEvent?.payload ?? {};
|
|
1856
|
+
const broker = payload?.broker ?? payload?.coordinator ?? payload?.leaderId ?? null;
|
|
1857
|
+
const error = payload?.error ? {
|
|
1858
|
+
type: payload.error.type ?? payload.error.name,
|
|
1859
|
+
message: payload.error.message
|
|
1860
|
+
} : void 0;
|
|
1861
|
+
const context = {
|
|
1862
|
+
event: eventName,
|
|
1863
|
+
timestamp: kafkaEvent?.timestamp ?? DateTime.now().value,
|
|
1864
|
+
broker,
|
|
1865
|
+
brokers: this.brokers,
|
|
1866
|
+
groupId: payload?.groupId,
|
|
1867
|
+
memberId: payload?.memberId,
|
|
1868
|
+
leaderId: payload?.leaderId,
|
|
1869
|
+
clientId: payload?.clientId,
|
|
1870
|
+
topicPartitions: payload?.topicPartitions,
|
|
1871
|
+
error
|
|
1872
|
+
};
|
|
1873
|
+
const message = `[KafkaManager][${eventName}] ${error?.message ?? ""}`.trim();
|
|
1874
|
+
if (level === "error") {
|
|
1875
|
+
console.error(message, context);
|
|
1876
|
+
await this.execCallback(this._onError, { message, context });
|
|
1877
|
+
} else {
|
|
1878
|
+
console.info(message, context);
|
|
1879
|
+
await this.execCallback(this._onReconnect, { message, context });
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
handleKafkaError(error, origin, metadata = {}) {
|
|
1883
|
+
if (!error)
|
|
1884
|
+
return;
|
|
1885
|
+
const errorType = error.type ?? error.name;
|
|
1886
|
+
const isNotLeaderError = errorType === "NOT_LEADER_FOR_PARTITION" || error?.name === "KafkaJSNotLeaderForPartition";
|
|
1887
|
+
if (!this.exitingDueToLeaderError && isNotLeaderError) {
|
|
1888
|
+
this.exitingDueToLeaderError = true;
|
|
1889
|
+
const payload = {
|
|
1890
|
+
origin,
|
|
1891
|
+
broker: error?.broker ?? metadata?.broker,
|
|
1892
|
+
topic: error?.topic,
|
|
1893
|
+
partition: error?.partition,
|
|
1894
|
+
metadata
|
|
1895
|
+
};
|
|
1896
|
+
console.error("[KafkaManager][NOT_LEADER_FOR_PARTITION] Forcing shutdown", payload);
|
|
1897
|
+
void this.execCallback(this._onCrash, {
|
|
1898
|
+
message: "[KafkaManager] NOT_LEADER_FOR_PARTITION detected. Forcing shutdown.",
|
|
1899
|
+
context: payload
|
|
1900
|
+
});
|
|
1901
|
+
setTimeout(() => this.runtimeProcess?.exit?.(1), 0);
|
|
1902
|
+
return;
|
|
1903
|
+
}
|
|
1904
|
+
if (error instanceof import_kafkajs.KafkaJSRequestTimeoutError || errorType === "REQUEST_TIMEOUT") {
|
|
1905
|
+
console.warn("[KafkaManager][REQUEST_TIMEOUT]", { origin, metadata });
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1801
1908
|
async commitMessage(topic, partition, message) {
|
|
1802
1909
|
const next = (BigInt(message.offset) + 1n).toString();
|
|
1803
1910
|
await this.consumer.commitOffsets([{ topic, partition, offset: next }]);
|
|
@@ -1806,7 +1913,7 @@ var KafkaManager = class extends EventManager {
|
|
|
1806
1913
|
const __run = async () => {
|
|
1807
1914
|
await this.execCallback(this._onStart, { message: `--- ${this.constructor.name} started ---` });
|
|
1808
1915
|
await this.consumer.connect();
|
|
1809
|
-
await this.execCallback(this._onConnected, { message: `--- ${this.constructor.name} connected to ${this.
|
|
1916
|
+
await this.execCallback(this._onConnected, { message: `--- ${this.constructor.name} connected to ${this.brokers.join(", ")} ---` });
|
|
1810
1917
|
for (let topic of this._topics) {
|
|
1811
1918
|
try {
|
|
1812
1919
|
await this.consumer.subscribe({ topic, fromBeginning: false });
|
|
@@ -1843,6 +1950,7 @@ var KafkaManager = class extends EventManager {
|
|
|
1843
1950
|
await heartbeat();
|
|
1844
1951
|
} catch (error) {
|
|
1845
1952
|
await this.execCallback(this._onError, error);
|
|
1953
|
+
this.handleKafkaError(error, "consumer.eachMessage", { topic, partition });
|
|
1846
1954
|
throw error;
|
|
1847
1955
|
}
|
|
1848
1956
|
}
|
|
@@ -1883,9 +1991,6 @@ var KafkaManager = class extends EventManager {
|
|
|
1883
1991
|
}
|
|
1884
1992
|
}
|
|
1885
1993
|
async start(autocommit = false) {
|
|
1886
|
-
this.consumer.on(this.consumer.events.CRASH, async (error) => {
|
|
1887
|
-
await this.execCallback(this._onError, new InternalError(ErrorManager.APP_ERRORS.PROCESS, error.payload.error.stack));
|
|
1888
|
-
});
|
|
1889
1994
|
await this.run();
|
|
1890
1995
|
}
|
|
1891
1996
|
async pause() {
|
|
@@ -2151,9 +2256,10 @@ var DefaultMysqlInboxRunner = class {
|
|
|
2151
2256
|
|
|
2152
2257
|
// src/infrastructure/runners/default-mysql-inbox-processor.ts
|
|
2153
2258
|
var DefaultMysqlInboxProcessor = class {
|
|
2154
|
-
constructor(uowFactory) {
|
|
2259
|
+
constructor(uowFactory, onError) {
|
|
2155
2260
|
this.uovFactory = uowFactory;
|
|
2156
2261
|
this.handlers = /* @__PURE__ */ new Map();
|
|
2262
|
+
this.onError = onError;
|
|
2157
2263
|
}
|
|
2158
2264
|
async sleep() {
|
|
2159
2265
|
return new Promise((r) => setTimeout(r, 5e3));
|
|
@@ -2175,6 +2281,13 @@ var DefaultMysqlInboxProcessor = class {
|
|
|
2175
2281
|
record.markProcessed();
|
|
2176
2282
|
} catch (error) {
|
|
2177
2283
|
record.markWithError(error.toString());
|
|
2284
|
+
if (this.onError) {
|
|
2285
|
+
try {
|
|
2286
|
+
this.onError(record, error);
|
|
2287
|
+
} catch (handlerError) {
|
|
2288
|
+
console.error("Error dentro del onError handler:", handlerError);
|
|
2289
|
+
}
|
|
2290
|
+
}
|
|
2178
2291
|
} finally {
|
|
2179
2292
|
await repository.update(record);
|
|
2180
2293
|
}
|