wsp-ms-core 1.1.24 → 1.1.26
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 +106 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +14 -5
- package/dist/index.d.ts +14 -5
- package/dist/index.js +106 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1781,10 +1781,22 @@ var KafkaManager = class extends EventManager {
|
|
|
1781
1781
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1782
1782
|
this.runtimeProcess = globalThis?.process;
|
|
1783
1783
|
this.producerConnected = false;
|
|
1784
|
-
this.
|
|
1785
|
-
this.
|
|
1784
|
+
this.isRecoveringLeader = false;
|
|
1785
|
+
this.seedBrokers = this.resolveBrokerList(this._connection.brokers ?? []);
|
|
1786
|
+
this.groupId = this.runtimeProcess?.env?.KAFKA_GROUP || "default";
|
|
1787
|
+
this.initializeKafkaClients(this.seedBrokers);
|
|
1788
|
+
this.leaderSelectionPromise = this.pinToLeaderBroker();
|
|
1789
|
+
}
|
|
1790
|
+
async ensureProducerConnected() {
|
|
1791
|
+
await this.waitForLeaderSelection();
|
|
1792
|
+
if (this.producerConnected)
|
|
1793
|
+
return;
|
|
1794
|
+
await this.producer.connect();
|
|
1795
|
+
this.producerConnected = true;
|
|
1796
|
+
}
|
|
1797
|
+
initializeKafkaClients(brokers) {
|
|
1786
1798
|
this.kafka = new import_kafkajs.Kafka({
|
|
1787
|
-
brokers
|
|
1799
|
+
brokers,
|
|
1788
1800
|
ssl: true,
|
|
1789
1801
|
sasl: {
|
|
1790
1802
|
mechanism: "scram-sha-256",
|
|
@@ -1793,16 +1805,92 @@ var KafkaManager = class extends EventManager {
|
|
|
1793
1805
|
},
|
|
1794
1806
|
logLevel: import_kafkajs.logLevel.ERROR
|
|
1795
1807
|
});
|
|
1796
|
-
|
|
1797
|
-
this.consumer = this.kafka.consumer({ groupId });
|
|
1808
|
+
this.consumer = this.kafka.consumer({ groupId: this.groupId });
|
|
1798
1809
|
this.producer = this.kafka.producer();
|
|
1810
|
+
this.brokers = brokers;
|
|
1811
|
+
this.producerConnected = false;
|
|
1799
1812
|
this.registerConsumerEventHandlers();
|
|
1800
1813
|
}
|
|
1801
|
-
async
|
|
1802
|
-
|
|
1814
|
+
async pinToLeaderBroker() {
|
|
1815
|
+
try {
|
|
1816
|
+
const leaderBroker = await this.fetchLeaderBroker(this.kafka);
|
|
1817
|
+
if (!leaderBroker) {
|
|
1818
|
+
console.warn("[KafkaManager] Unable to determine leader broker. Using configured list.", { brokers: this.brokers });
|
|
1819
|
+
return;
|
|
1820
|
+
}
|
|
1821
|
+
if (this.brokers.length === 1 && this.brokers[0] === leaderBroker) {
|
|
1822
|
+
return;
|
|
1823
|
+
}
|
|
1824
|
+
console.info("[KafkaManager] Leader broker resolved. Reinitializing clients", { leaderBroker });
|
|
1825
|
+
this.initializeKafkaClients([leaderBroker]);
|
|
1826
|
+
} catch (error) {
|
|
1827
|
+
console.warn("[KafkaManager] Error resolving leader broker. Falling back to configured brokers.", error);
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
buildKafkaClient(brokers) {
|
|
1831
|
+
return new import_kafkajs.Kafka({
|
|
1832
|
+
brokers,
|
|
1833
|
+
ssl: true,
|
|
1834
|
+
sasl: {
|
|
1835
|
+
mechanism: "scram-sha-256",
|
|
1836
|
+
username: this._connection.userName,
|
|
1837
|
+
password: this._connection.password
|
|
1838
|
+
},
|
|
1839
|
+
logLevel: import_kafkajs.logLevel.ERROR
|
|
1840
|
+
});
|
|
1841
|
+
}
|
|
1842
|
+
async fetchLeaderBroker(kafkaClient) {
|
|
1843
|
+
const admin = kafkaClient.admin();
|
|
1844
|
+
try {
|
|
1845
|
+
await admin.connect();
|
|
1846
|
+
const cluster = await admin.describeCluster();
|
|
1847
|
+
const controllerId = cluster?.controller;
|
|
1848
|
+
const controller = controllerId !== void 0 ? cluster?.brokers?.find((node) => node.nodeId === controllerId) : void 0;
|
|
1849
|
+
if (!controller?.host) {
|
|
1850
|
+
return null;
|
|
1851
|
+
}
|
|
1852
|
+
const host = controller.host;
|
|
1853
|
+
const port = controller.port ?? 9092;
|
|
1854
|
+
return this.normalizeBroker(`${host}:${port}`);
|
|
1855
|
+
} finally {
|
|
1856
|
+
await admin.disconnect().catch(() => void 0);
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
async recoverFromLeaderChange(origin) {
|
|
1860
|
+
if (this.isRecoveringLeader)
|
|
1803
1861
|
return;
|
|
1804
|
-
|
|
1805
|
-
this.
|
|
1862
|
+
this.isRecoveringLeader = true;
|
|
1863
|
+
console.warn("[KafkaManager] Recovering from leader change", { origin, brokers: this.brokers });
|
|
1864
|
+
await this.execCallback(this._onReconnect, {
|
|
1865
|
+
message: "[KafkaManager] Leader change detected. Reconnecting to new leader.",
|
|
1866
|
+
context: { origin }
|
|
1867
|
+
});
|
|
1868
|
+
try {
|
|
1869
|
+
await this.stop().catch((error) => {
|
|
1870
|
+
console.warn("[KafkaManager] Error stopping previous connection during recovery", error);
|
|
1871
|
+
});
|
|
1872
|
+
const seedClient = this.buildKafkaClient(this.seedBrokers);
|
|
1873
|
+
const leaderBroker = await this.fetchLeaderBroker(seedClient).catch((error) => {
|
|
1874
|
+
console.warn("[KafkaManager] Error resolving new leader broker during recovery", error);
|
|
1875
|
+
return null;
|
|
1876
|
+
});
|
|
1877
|
+
const brokersToUse = leaderBroker ? [leaderBroker] : this.seedBrokers;
|
|
1878
|
+
console.info("[KafkaManager] Reconnecting using brokers", { brokersToUse });
|
|
1879
|
+
this.initializeKafkaClients(brokersToUse);
|
|
1880
|
+
this.leaderSelectionPromise = Promise.resolve();
|
|
1881
|
+
await this.run();
|
|
1882
|
+
} catch (error) {
|
|
1883
|
+
console.error("[KafkaManager] Failed to recover from leader change", { origin, error });
|
|
1884
|
+
await this.execCallback(this._onError, error);
|
|
1885
|
+
} finally {
|
|
1886
|
+
this.isRecoveringLeader = false;
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
async waitForLeaderSelection() {
|
|
1890
|
+
try {
|
|
1891
|
+
await this.leaderSelectionPromise;
|
|
1892
|
+
} catch {
|
|
1893
|
+
}
|
|
1806
1894
|
}
|
|
1807
1895
|
resolveBrokerList(brokers) {
|
|
1808
1896
|
const envBrokers = (this.runtimeProcess?.env?.KAFKA_BROKERS ?? "").split(",").map((value) => value.trim()).filter(Boolean);
|
|
@@ -1843,6 +1931,9 @@ var KafkaManager = class extends EventManager {
|
|
|
1843
1931
|
this.consumer.on(events.CRASH, async (event) => {
|
|
1844
1932
|
await this.logConsumerEvent("CRASH", event, "error");
|
|
1845
1933
|
this.handleKafkaError(event?.payload?.error, "consumer.CRASH", { broker: event?.payload?.broker });
|
|
1934
|
+
if (event?.payload?.restart === false) {
|
|
1935
|
+
void this.recoverFromLeaderChange("consumer.CRASH.no-restart");
|
|
1936
|
+
}
|
|
1846
1937
|
});
|
|
1847
1938
|
this.consumer.on(events.DISCONNECT, async (event) => {
|
|
1848
1939
|
await this.logConsumerEvent("DISCONNECT", event, "error");
|
|
@@ -1884,8 +1975,7 @@ var KafkaManager = class extends EventManager {
|
|
|
1884
1975
|
return;
|
|
1885
1976
|
const errorType = error.type ?? error.name;
|
|
1886
1977
|
const isNotLeaderError = errorType === "NOT_LEADER_FOR_PARTITION" || error?.name === "KafkaJSNotLeaderForPartition";
|
|
1887
|
-
if (
|
|
1888
|
-
this.exitingDueToLeaderError = true;
|
|
1978
|
+
if (isNotLeaderError) {
|
|
1889
1979
|
const payload = {
|
|
1890
1980
|
origin,
|
|
1891
1981
|
broker: error?.broker ?? metadata?.broker,
|
|
@@ -1893,12 +1983,12 @@ var KafkaManager = class extends EventManager {
|
|
|
1893
1983
|
partition: error?.partition,
|
|
1894
1984
|
metadata
|
|
1895
1985
|
};
|
|
1896
|
-
console.error("[KafkaManager][NOT_LEADER_FOR_PARTITION]
|
|
1986
|
+
console.error("[KafkaManager][NOT_LEADER_FOR_PARTITION] Reconnecting to new leader", payload);
|
|
1897
1987
|
void this.execCallback(this._onCrash, {
|
|
1898
|
-
message: "[KafkaManager] NOT_LEADER_FOR_PARTITION detected.
|
|
1988
|
+
message: "[KafkaManager] NOT_LEADER_FOR_PARTITION detected. Reconnecting to new leader.",
|
|
1899
1989
|
context: payload
|
|
1900
1990
|
});
|
|
1901
|
-
|
|
1991
|
+
void this.recoverFromLeaderChange(origin);
|
|
1902
1992
|
return;
|
|
1903
1993
|
}
|
|
1904
1994
|
if (error instanceof import_kafkajs.KafkaJSRequestTimeoutError || errorType === "REQUEST_TIMEOUT") {
|
|
@@ -1911,6 +2001,7 @@ var KafkaManager = class extends EventManager {
|
|
|
1911
2001
|
}
|
|
1912
2002
|
async run(autocommit = false) {
|
|
1913
2003
|
const __run = async () => {
|
|
2004
|
+
await this.waitForLeaderSelection();
|
|
1914
2005
|
await this.execCallback(this._onStart, { message: `--- ${this.constructor.name} started ---` });
|
|
1915
2006
|
await this.consumer.connect();
|
|
1916
2007
|
await this.execCallback(this._onConnected, { message: `--- ${this.constructor.name} connected to ${this.brokers.join(", ")} ---` });
|
|
@@ -1963,6 +2054,7 @@ var KafkaManager = class extends EventManager {
|
|
|
1963
2054
|
}
|
|
1964
2055
|
}
|
|
1965
2056
|
async send(e) {
|
|
2057
|
+
await this.waitForLeaderSelection();
|
|
1966
2058
|
const evt = {
|
|
1967
2059
|
date: DateTime.now().value,
|
|
1968
2060
|
tenant: e.tenant.value,
|