@uns-kit/core 0.0.36 → 0.0.37
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/LICENSE +21 -21
- package/README.md +55 -55
- package/dist/app-config.js.map +1 -1
- package/dist/base-path.js.map +1 -1
- package/dist/config/app-config.js.map +1 -1
- package/dist/config/project.config.extension.js.map +1 -1
- package/dist/config-file.js.map +1 -1
- package/dist/graphql/schema.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/logger.js.map +1 -1
- package/dist/tools/auth/auth-client.js.map +1 -1
- package/dist/tools/auth/index.js.map +1 -1
- package/dist/tools/auth/secure-store.js.map +1 -1
- package/dist/tools/base-path.js.map +1 -1
- package/dist/tools/generate-config-schema.js.map +1 -1
- package/dist/tools/initialize.d.ts +1 -1
- package/dist/tools/initialize.d.ts.map +1 -0
- package/dist/tools/initialize.js +103 -103
- package/dist/tools/initialize.js.map +1 -0
- package/dist/tools/make.d.ts +1 -1
- package/dist/tools/make.d.ts.map +1 -0
- package/dist/tools/make.js +27 -27
- package/dist/tools/make.js.map +1 -0
- package/dist/tools/pull-request.js.map +1 -1
- package/dist/tools/refresh-uns.js +35 -35
- package/dist/tools/refresh-uns.js.map +1 -1
- package/dist/tools/schema.js.map +1 -1
- package/dist/tools/update-rtt.d.ts +1 -1
- package/dist/tools/update-rtt.d.ts.map +1 -0
- package/dist/tools/update-rtt.js +169 -169
- package/dist/tools/update-rtt.js.map +1 -0
- package/dist/tools/update-tools.d.ts +1 -1
- package/dist/tools/update-tools.d.ts.map +1 -0
- package/dist/tools/update-tools.js +72 -72
- package/dist/tools/update-tools.js.map +1 -0
- package/dist/uns/handover-manager-event-emitter.js.map +1 -1
- package/dist/uns/handover-manager.js.map +1 -1
- package/dist/uns/process-config.js.map +1 -1
- package/dist/uns/process-name-service.js.map +1 -1
- package/dist/uns/status-monitor.js.map +1 -1
- package/dist/uns/uns-event-emitter.js.map +1 -1
- package/dist/uns/uns-interfaces.js.map +1 -1
- package/dist/uns/uns-measurements.js.map +1 -1
- package/dist/uns/uns-packet.js.map +1 -1
- package/dist/uns/uns-proxy-process.js.map +1 -1
- package/dist/uns/uns-proxy.js.map +1 -1
- package/dist/uns/uns-tags.js.map +1 -1
- package/dist/uns/uns-topic-matcher.js.map +1 -1
- package/dist/uns/uns-topics.js.map +1 -1
- package/dist/uns-config/config-schema.js.map +1 -1
- package/dist/uns-config/host-placeholders.js.map +1 -1
- package/dist/uns-config/schema-tolls.js.map +1 -1
- package/dist/uns-config/schema-tools.js.map +1 -1
- package/dist/uns-config/secret-placeholders.js.map +1 -1
- package/dist/uns-config/secret-resolver.js.map +1 -1
- package/dist/uns-config/uns-core-schema.js.map +1 -1
- package/dist/uns-grpc/uns-gateway-cli.js.map +1 -1
- package/dist/uns-grpc/uns-gateway-server.js.map +1 -1
- package/dist/uns-grpc/uns-gateway.proto +102 -102
- package/dist/uns-mqtt/mqtt-interfaces.js.map +1 -1
- package/dist/uns-mqtt/mqtt-proxy.js.map +1 -1
- package/dist/uns-mqtt/mqtt-topic-builder.js.map +1 -1
- package/dist/uns-mqtt/mqtt-worker-init.js.map +1 -1
- package/dist/uns-mqtt/mqtt-worker.js.map +1 -1
- package/dist/uns-mqtt/throttled-queue.js.map +1 -1
- package/dist/uns-mqtt/uns-mqtt-proxy.js.map +1 -1
- package/dist/uns-mqtt/ws-proxy.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mqtt-proxy.js","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import mqtt, { IClientOptions, MqttClient } from \"mqtt\";\r\nimport logger from \"../logger.js\";\r\nimport { UnsEvents } from \"../uns/uns-interfaces.js\";\r\nimport { UnsEventEmitter } from \"../uns/uns-event-emitter.js\";\r\nimport { IMqttParameters } from \"./mqtt-interfaces.js\";\r\nimport { MqttWorker } from \"./mqtt-worker.js\";\r\nimport { DataSizeMeasurements, PhysicalMeasurements } from \"../uns/uns-measurements.js\";\r\n\r\nexport default class MqttProxy {\r\n public event: UnsEventEmitter<UnsEvents> = new UnsEventEmitter<UnsEvents>();\r\n public statusTopic: string;\r\n public instanceName: string;\r\n private mqttHost: string;\r\n private mqttSubToTopics: string | string[];\r\n private mqttSSL: boolean;\r\n private mqttClient: MqttClient;\r\n private startDate: Date;\r\n private mqttParameters: IMqttParameters;\r\n private statusUpdateInterval: ReturnType<typeof setInterval>;\r\n private transformationStatsInterval: NodeJS.Timeout | null = null;\r\n private publishedMessageCount = 0;\r\n private publishedMessageBytes = 0;\r\n private subscribedMessageCount = 0;\r\n private subscribedMessageBytes = 0;\r\n private mqttWorker: MqttWorker;\r\n public isConnected = false;\r\n\r\n constructor(mqttHost: string, instanceName: string, mqttParameters: IMqttParameters, mqttWorker?: MqttWorker) {\r\n this.mqttSSL = mqttParameters?.mqttSSL ?? false;\r\n this.mqttSubToTopics = mqttParameters?.mqttSubToTopics ?? [];\r\n this.mqttHost = mqttHost;\r\n this.startDate = new Date();\r\n this.instanceName = instanceName ?? \"process\";\r\n this.statusTopic = `${mqttParameters?.statusTopic}`;\r\n this.mqttParameters = mqttParameters ?? {};\r\n this.mqttWorker = mqttWorker;\r\n }\r\n\r\n public async start(): Promise<void> {\r\n logger.info(`${this.instanceName} - Connecting to MQTT broker...`);\r\n\r\n return new Promise<void>((resolve, reject) => {\r\n try {\r\n const username = this.mqttParameters.username;\r\n const password = this.mqttParameters.password;\r\n\r\n const options: IClientOptions = {\r\n username,\r\n password,\r\n protocolVersion: 5,\r\n rejectUnauthorized: this.mqttSSL,\r\n will: {\r\n topic: `${this.statusTopic}alive`,\r\n payload: Buffer.from(\"\"),\r\n qos: 0,\r\n retain: true,\r\n properties: { messageExpiryInterval: 3600 },\r\n },\r\n clientId: this.instanceName,\r\n clean: true,\r\n };\r\n\r\n const protocol = this.mqttSSL ? \"mqtts\" : \"mqtt\";\r\n this.mqttClient = mqtt.connect(`${protocol}://${this.mqttHost}`, options);\r\n\r\n const onConnect = () => {\r\n try {\r\n this.mqttClient.stream.setMaxListeners(0);\r\n logger.info(`${this.instanceName} - Connected to MQTT broker at ${this.mqttHost}`);\r\n\r\n if (this.mqttSubToTopics && this.mqttSubToTopics.length > 0) {\r\n logger.info(`${this.instanceName} - Subscribed to ${this.mqttSubToTopics.length} topics.`);\r\n this.mqttClient.subscribe(this.mqttSubToTopics, { qos: 0 });\r\n }\r\n\r\n if (this.statusTopic) {\r\n this.statusUpdateInterval = setInterval(() => this.emitStatusUpdates(), 10000);\r\n }\r\n\r\n this.transformationStatsInterval = setInterval(() => {\r\n this.emitTransformationStatistics();\r\n }, 60000);\r\n\r\n this.mqttClient.off(\"connect\", onConnect);\r\n this.isConnected = true;\r\n resolve();\r\n } catch (error) {\r\n logger.error(`${this.instanceName} - Error in MQTT connect handler: ${error.message}`);\r\n this.isConnected = false;\r\n reject(error);\r\n }\r\n };\r\n\r\n this.mqttClient.on(\"connect\", onConnect);\r\n\r\n this.mqttClient.on(\"message\", (topic: string, message: Buffer, packet: mqtt.IPublishPacket) => {\r\n try {\r\n logger.debug(`${this.instanceName} - Message received on topic ${topic}`);\r\n this.event.emit(\"input\", {\r\n message: message.toString(),\r\n topic: topic,\r\n packet: packet,\r\n });\r\n this.updateSubscribeTransformationStats(message.length);\r\n } catch (error) {\r\n logger.error(`${this.instanceName} - Error in MQTT message handler: ${error.message}`);\r\n }\r\n });\r\n\r\n this.mqttClient.on(\"error\", (error) => {\r\n logger.error(`${this.instanceName} - MQTT client error: ${error.message}`);\r\n this.isConnected = false;\r\n if (\"code\" in error) {\r\n this.event.emit(\"error\", { code: error.code, message: error.message });\r\n } else {\r\n this.event.emit(\"error\", { message: error.message, code: 0 });\r\n }\r\n reject(error);\r\n });\r\n\r\n this.mqttClient.on(\"reconnect\", () => {\r\n logger.debug(`${this.instanceName} - Attempting to reconnect to MQTT broker...`);\r\n });\r\n\r\n this.mqttClient.on(\"close\", () => {\r\n logger.debug(`${this.instanceName} - MQTT connection closed.`);\r\n this.isConnected = false;\r\n });\r\n\r\n this.mqttClient.on(\"offline\", () => {\r\n logger.debug(`${this.instanceName} - MQTT client is offline.`);\r\n this.isConnected = false;\r\n });\r\n\r\n this.mqttClient.on(\"end\", () => {\r\n logger.debug(`${this.instanceName} - MQTT client connection ended.`);\r\n this.isConnected = false;\r\n });\r\n\r\n this.mqttClient.on(\"disconnect\", (packet) => {\r\n logger.debug(`${this.instanceName} - MQTT client disconnected. Reason: ${packet?.reasonCode}`);\r\n this.isConnected = false;\r\n });\r\n } catch (error) {\r\n logger.error(`${this.instanceName} - Error starting MQTT proxy: ${error.message}`);\r\n this.isConnected = false;\r\n reject(error);\r\n }\r\n });\r\n }\r\n\r\n public async publish(topic: string, message: string | Buffer, options?: mqtt.IClientPublishOptions): Promise<void> {\r\n this.updatePublishTransformationStats(JSON.stringify(message).length);\r\n return new Promise((resolve, reject) => {\r\n if (!this.mqttClient || !this.mqttClient.connected) {\r\n const error = new Error(`${this.instanceName} - MQTT client is not connected.`);\r\n logger.error(error.message);\r\n return reject(error);\r\n }\r\n\r\n this.mqttClient.publish(topic, message, options || {}, (err) => {\r\n if (err) {\r\n logger.error(`${this.instanceName} - Error publishing to topic ${topic}: ${err.message}`);\r\n return reject(err);\r\n }\r\n logger.debug(`${this.instanceName} - Published message to topic ${topic}`);\r\n resolve();\r\n });\r\n });\r\n }\r\n\r\n public async subscribeAsync(topic: string | string[], options?: mqtt.IClientSubscribeOptions): Promise<mqtt.ISubscriptionGrant[]> {\r\n return this.mqttClient.subscribeAsync(topic, options);\r\n }\r\n\r\n public async unsubscribeAsync(topic: string | string[]): Promise<mqtt.Packet | undefined> {\r\n return this.mqttClient.unsubscribeAsync(topic);\r\n }\r\n\r\n public stop() {\r\n logger.info(`${this.instanceName} - Disconnecting from MQTT broker...`);\r\n try {\r\n if (this.statusUpdateInterval) {\r\n clearInterval(this.statusUpdateInterval);\r\n this.statusUpdateInterval = null;\r\n }\r\n if (this.transformationStatsInterval) {\r\n clearInterval(this.transformationStatsInterval);\r\n this.transformationStatsInterval = null;\r\n }\r\n if (this.mqttClient) {\r\n this.mqttClient.end(false, () => {\r\n this.isConnected = false;\r\n logger.info(`${this.instanceName} - Disconnected from MQTT broker.`);\r\n });\r\n }\r\n } catch (error) {\r\n logger.error(`${this.instanceName} - Error during stop: ${error.message}`);\r\n this.isConnected = false;\r\n }\r\n }\r\n\r\n private emitStatusUpdates() {\r\n try {\r\n const uptime = Math.round((new Date().getTime() - this.startDate.getTime()) / 60000);\r\n this.event.emit(\"mqttProxyStatus\", { event: \"uptime\", value: uptime, uom: PhysicalMeasurements.Minute, statusTopic: this.statusTopic + \"uptime\" });\r\n this.event.emit(\"mqttProxyStatus\", { event: \"alive\", value: 1, uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + \"alive\" });\r\n\r\n if (this.mqttWorker !== undefined) {\r\n const tpValue = this.mqttWorker.getPublisherState() ? 1 : 0;\r\n this.event.emit(\"mqttProxyStatus\", { event: \"t-publisher-active\", value: tpValue, uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + \"t-publisher-active\" });\r\n const tsValue = this.mqttWorker.getSubscriberState() ? 1 : 0;\r\n this.event.emit(\"mqttProxyStatus\", { event: \"t-subscriber-active\", value: tsValue, uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + \"t-subscriber-active\" });\r\n }\r\n } catch (error) {\r\n logger.error(`${this.instanceName} - Error publishing MQTT status: ${error.message}`);\r\n }\r\n }\r\n\r\n private updatePublishTransformationStats(messageSizeOut: number): void {\r\n this.publishedMessageCount += 1;\r\n this.publishedMessageBytes += messageSizeOut;\r\n }\r\n\r\n private updateSubscribeTransformationStats(messageSizeIn: number): void {\r\n this.subscribedMessageCount += 1;\r\n this.subscribedMessageBytes += messageSizeIn;\r\n }\r\n\r\n private async emitTransformationStatistics(): Promise<void> {\r\n if (this.statusTopic !== \"\") {\r\n try {\r\n this.event.emit(\"mqttProxyStatus\", {\r\n event: \"published-message-count\",\r\n value: this.publishedMessageCount,\r\n uom: \"\",\r\n statusTopic: this.statusTopic + \"published-message-count\",\r\n });\r\n this.event.emit(\"mqttProxyStatus\", {\r\n event: \"published-message-bytes\",\r\n value: Math.round(this.publishedMessageBytes / 1024),\r\n uom: DataSizeMeasurements.KiloByte,\r\n statusTopic: this.statusTopic + \"published-message-bytes\",\r\n });\r\n this.event.emit(\"mqttProxyStatus\", {\r\n event: \"subscribed-message-count\",\r\n value: this.subscribedMessageCount,\r\n uom: \"\",\r\n statusTopic: this.statusTopic + \"subscribed-message-count\",\r\n });\r\n this.event.emit(\"mqttProxyStatus\", {\r\n event: \"subscribed-message-bytes\",\r\n value: Math.round(this.subscribedMessageBytes / 1024),\r\n uom: DataSizeMeasurements.KiloByte,\r\n statusTopic: this.statusTopic + \"subscribed-message-bytes\",\r\n });\r\n this.publishedMessageCount = 0;\r\n this.publishedMessageBytes = 0;\r\n this.subscribedMessageCount = 0;\r\n this.subscribedMessageBytes = 0;\r\n } catch (error: any) {\r\n this.publishedMessageCount = 0;\r\n this.publishedMessageBytes = 0;\r\n this.subscribedMessageCount = 0;\r\n this.subscribedMessageBytes = 0;\r\n logger.error(`${this.instanceName} - Error emitting transformation statistics: ${error.message}`);\r\n }\r\n }\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"mqtt-proxy.js","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import mqtt, { IClientOptions, MqttClient } from \"mqtt\";\nimport logger from \"../logger.js\";\nimport { UnsEvents } from \"../uns/uns-interfaces.js\";\nimport { UnsEventEmitter } from \"../uns/uns-event-emitter.js\";\nimport { IMqttParameters } from \"./mqtt-interfaces.js\";\nimport { MqttWorker } from \"./mqtt-worker.js\";\nimport { DataSizeMeasurements, PhysicalMeasurements } from \"../uns/uns-measurements.js\";\n\nexport default class MqttProxy {\n public event: UnsEventEmitter<UnsEvents> = new UnsEventEmitter<UnsEvents>();\n public statusTopic: string;\n public instanceName: string;\n private mqttHost: string;\n private mqttSubToTopics: string | string[];\n private mqttSSL: boolean;\n private mqttClient: MqttClient;\n private startDate: Date;\n private mqttParameters: IMqttParameters;\n private statusUpdateInterval: ReturnType<typeof setInterval>;\n private transformationStatsInterval: NodeJS.Timeout | null = null;\n private publishedMessageCount = 0;\n private publishedMessageBytes = 0;\n private subscribedMessageCount = 0;\n private subscribedMessageBytes = 0;\n private mqttWorker: MqttWorker;\n public isConnected = false;\n\n constructor(mqttHost: string, instanceName: string, mqttParameters: IMqttParameters, mqttWorker?: MqttWorker) {\n this.mqttSSL = mqttParameters?.mqttSSL ?? false;\n this.mqttSubToTopics = mqttParameters?.mqttSubToTopics ?? [];\n this.mqttHost = mqttHost;\n this.startDate = new Date();\n this.instanceName = instanceName ?? \"process\";\n this.statusTopic = `${mqttParameters?.statusTopic}`;\n this.mqttParameters = mqttParameters ?? {};\n this.mqttWorker = mqttWorker;\n }\n\n public async start(): Promise<void> {\n logger.info(`${this.instanceName} - Connecting to MQTT broker...`);\n\n return new Promise<void>((resolve, reject) => {\n try {\n const username = this.mqttParameters.username;\n const password = this.mqttParameters.password;\n\n const options: IClientOptions = {\n username,\n password,\n protocolVersion: 5,\n rejectUnauthorized: this.mqttSSL,\n will: {\n topic: `${this.statusTopic}alive`,\n payload: Buffer.from(\"\"),\n qos: 0,\n retain: true,\n properties: { messageExpiryInterval: 3600 },\n },\n clientId: this.instanceName,\n clean: true,\n };\n\n const protocol = this.mqttSSL ? \"mqtts\" : \"mqtt\";\n this.mqttClient = mqtt.connect(`${protocol}://${this.mqttHost}`, options);\n\n const onConnect = () => {\n try {\n this.mqttClient.stream.setMaxListeners(0);\n logger.info(`${this.instanceName} - Connected to MQTT broker at ${this.mqttHost}`);\n\n if (this.mqttSubToTopics && this.mqttSubToTopics.length > 0) {\n logger.info(`${this.instanceName} - Subscribed to ${this.mqttSubToTopics.length} topics.`);\n this.mqttClient.subscribe(this.mqttSubToTopics, { qos: 0 });\n }\n\n if (this.statusTopic) {\n this.statusUpdateInterval = setInterval(() => this.emitStatusUpdates(), 10000);\n }\n\n this.transformationStatsInterval = setInterval(() => {\n this.emitTransformationStatistics();\n }, 60000);\n\n this.mqttClient.off(\"connect\", onConnect);\n this.isConnected = true;\n resolve();\n } catch (error) {\n logger.error(`${this.instanceName} - Error in MQTT connect handler: ${error.message}`);\n this.isConnected = false;\n reject(error);\n }\n };\n\n this.mqttClient.on(\"connect\", onConnect);\n\n this.mqttClient.on(\"message\", (topic: string, message: Buffer, packet: mqtt.IPublishPacket) => {\n try {\n logger.debug(`${this.instanceName} - Message received on topic ${topic}`);\n this.event.emit(\"input\", {\n message: message.toString(),\n topic: topic,\n packet: packet,\n });\n this.updateSubscribeTransformationStats(message.length);\n } catch (error) {\n logger.error(`${this.instanceName} - Error in MQTT message handler: ${error.message}`);\n }\n });\n\n this.mqttClient.on(\"error\", (error) => {\n logger.error(`${this.instanceName} - MQTT client error: ${error.message}`);\n this.isConnected = false;\n if (\"code\" in error) {\n this.event.emit(\"error\", { code: error.code, message: error.message });\n } else {\n this.event.emit(\"error\", { message: error.message, code: 0 });\n }\n reject(error);\n });\n\n this.mqttClient.on(\"reconnect\", () => {\n logger.debug(`${this.instanceName} - Attempting to reconnect to MQTT broker...`);\n });\n\n this.mqttClient.on(\"close\", () => {\n logger.debug(`${this.instanceName} - MQTT connection closed.`);\n this.isConnected = false;\n });\n\n this.mqttClient.on(\"offline\", () => {\n logger.debug(`${this.instanceName} - MQTT client is offline.`);\n this.isConnected = false;\n });\n\n this.mqttClient.on(\"end\", () => {\n logger.debug(`${this.instanceName} - MQTT client connection ended.`);\n this.isConnected = false;\n });\n\n this.mqttClient.on(\"disconnect\", (packet) => {\n logger.debug(`${this.instanceName} - MQTT client disconnected. Reason: ${packet?.reasonCode}`);\n this.isConnected = false;\n });\n } catch (error) {\n logger.error(`${this.instanceName} - Error starting MQTT proxy: ${error.message}`);\n this.isConnected = false;\n reject(error);\n }\n });\n }\n\n public async publish(topic: string, message: string | Buffer, options?: mqtt.IClientPublishOptions): Promise<void> {\n this.updatePublishTransformationStats(JSON.stringify(message).length);\n return new Promise((resolve, reject) => {\n if (!this.mqttClient || !this.mqttClient.connected) {\n const error = new Error(`${this.instanceName} - MQTT client is not connected.`);\n logger.error(error.message);\n return reject(error);\n }\n\n this.mqttClient.publish(topic, message, options || {}, (err) => {\n if (err) {\n logger.error(`${this.instanceName} - Error publishing to topic ${topic}: ${err.message}`);\n return reject(err);\n }\n logger.debug(`${this.instanceName} - Published message to topic ${topic}`);\n resolve();\n });\n });\n }\n\n public async subscribeAsync(topic: string | string[], options?: mqtt.IClientSubscribeOptions): Promise<mqtt.ISubscriptionGrant[]> {\n return this.mqttClient.subscribeAsync(topic, options);\n }\n\n public async unsubscribeAsync(topic: string | string[]): Promise<mqtt.Packet | undefined> {\n return this.mqttClient.unsubscribeAsync(topic);\n }\n\n public stop() {\n logger.info(`${this.instanceName} - Disconnecting from MQTT broker...`);\n try {\n if (this.statusUpdateInterval) {\n clearInterval(this.statusUpdateInterval);\n this.statusUpdateInterval = null;\n }\n if (this.transformationStatsInterval) {\n clearInterval(this.transformationStatsInterval);\n this.transformationStatsInterval = null;\n }\n if (this.mqttClient) {\n this.mqttClient.end(false, () => {\n this.isConnected = false;\n logger.info(`${this.instanceName} - Disconnected from MQTT broker.`);\n });\n }\n } catch (error) {\n logger.error(`${this.instanceName} - Error during stop: ${error.message}`);\n this.isConnected = false;\n }\n }\n\n private emitStatusUpdates() {\n try {\n const uptime = Math.round((new Date().getTime() - this.startDate.getTime()) / 60000);\n this.event.emit(\"mqttProxyStatus\", { event: \"uptime\", value: uptime, uom: PhysicalMeasurements.Minute, statusTopic: this.statusTopic + \"uptime\" });\n this.event.emit(\"mqttProxyStatus\", { event: \"alive\", value: 1, uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + \"alive\" });\n\n if (this.mqttWorker !== undefined) {\n const tpValue = this.mqttWorker.getPublisherState() ? 1 : 0;\n this.event.emit(\"mqttProxyStatus\", { event: \"t-publisher-active\", value: tpValue, uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + \"t-publisher-active\" });\n const tsValue = this.mqttWorker.getSubscriberState() ? 1 : 0;\n this.event.emit(\"mqttProxyStatus\", { event: \"t-subscriber-active\", value: tsValue, uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + \"t-subscriber-active\" });\n }\n } catch (error) {\n logger.error(`${this.instanceName} - Error publishing MQTT status: ${error.message}`);\n }\n }\n\n private updatePublishTransformationStats(messageSizeOut: number): void {\n this.publishedMessageCount += 1;\n this.publishedMessageBytes += messageSizeOut;\n }\n\n private updateSubscribeTransformationStats(messageSizeIn: number): void {\n this.subscribedMessageCount += 1;\n this.subscribedMessageBytes += messageSizeIn;\n }\n\n private async emitTransformationStatistics(): Promise<void> {\n if (this.statusTopic !== \"\") {\n try {\n this.event.emit(\"mqttProxyStatus\", {\n event: \"published-message-count\",\n value: this.publishedMessageCount,\n uom: \"\",\n statusTopic: this.statusTopic + \"published-message-count\",\n });\n this.event.emit(\"mqttProxyStatus\", {\n event: \"published-message-bytes\",\n value: Math.round(this.publishedMessageBytes / 1024),\n uom: DataSizeMeasurements.KiloByte,\n statusTopic: this.statusTopic + \"published-message-bytes\",\n });\n this.event.emit(\"mqttProxyStatus\", {\n event: \"subscribed-message-count\",\n value: this.subscribedMessageCount,\n uom: \"\",\n statusTopic: this.statusTopic + \"subscribed-message-count\",\n });\n this.event.emit(\"mqttProxyStatus\", {\n event: \"subscribed-message-bytes\",\n value: Math.round(this.subscribedMessageBytes / 1024),\n uom: DataSizeMeasurements.KiloByte,\n statusTopic: this.statusTopic + \"subscribed-message-bytes\",\n });\n this.publishedMessageCount = 0;\n this.publishedMessageBytes = 0;\n this.subscribedMessageCount = 0;\n this.subscribedMessageBytes = 0;\n } catch (error: any) {\n this.publishedMessageCount = 0;\n this.publishedMessageBytes = 0;\n this.subscribedMessageCount = 0;\n this.subscribedMessageBytes = 0;\n logger.error(`${this.instanceName} - Error emitting transformation statistics: ${error.message}`);\n }\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mqtt-topic-builder.js","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-topic-builder.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,OAAO,gBAAgB;IACjB,kBAAkB,CAAS;IAEnC;;;;;OAKG;IACH,YAAY,kBAA0B;QAEpC,IAAI,CAAC,oCAAoC,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACnE,MAAM,IAAI,KAAK,CAAC,+FAA+F,CAAC,CAAC;QACnH,CAAC;QACD,IAAI,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;IAC/C,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,iBAAiB,CAAC,IAAY;QAC1C,MAAM,SAAS,GAAG,IAAI;aACnB,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC;aAChC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;aACtB,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAE3B,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC;IAC1D,CAAC;IAAA,CAAC;IAEF;;;;OAIG;IACI,qBAAqB;QAC1B,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACI,cAAc;QACnB,OAAO,IAAI,CAAC,qBAAqB,EAAE,GAAG,QAAQ,CAAC;IACjD,CAAC;IAED;;;;OAIG;IACI,gBAAgB;QACrB,OAAO,IAAI,CAAC,qBAAqB,EAAE,GAAG,UAAU,CAAC;IACnD,CAAC;IAED;;;;;OAKG;IACI,sBAAsB;QAC3B,OAAO,IAAI,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC;IACvF,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,gBAAgB,CAAC,SAAiB;QAC9C,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,oFAAoF,CAAC,CAAC;QACxG,CAAC;QACD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IAC3C,CAAC;CACF","sourcesContent":["/**\
|
|
1
|
+
{"version":3,"file":"mqtt-topic-builder.js","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-topic-builder.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,OAAO,gBAAgB;IACjB,kBAAkB,CAAS;IAEnC;;;;;OAKG;IACH,YAAY,kBAA0B;QAEpC,IAAI,CAAC,oCAAoC,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACnE,MAAM,IAAI,KAAK,CAAC,+FAA+F,CAAC,CAAC;QACnH,CAAC;QACD,IAAI,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;IAC/C,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,iBAAiB,CAAC,IAAY;QAC1C,MAAM,SAAS,GAAG,IAAI;aACnB,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC;aAChC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;aACtB,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAE3B,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC;IAC1D,CAAC;IAAA,CAAC;IAEF;;;;OAIG;IACI,qBAAqB;QAC1B,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACI,cAAc;QACnB,OAAO,IAAI,CAAC,qBAAqB,EAAE,GAAG,QAAQ,CAAC;IACjD,CAAC;IAED;;;;OAIG;IACI,gBAAgB;QACrB,OAAO,IAAI,CAAC,qBAAqB,EAAE,GAAG,UAAU,CAAC;IACnD,CAAC;IAED;;;;;OAKG;IACI,sBAAsB;QAC3B,OAAO,IAAI,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC;IACvF,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,gBAAgB,CAAC,SAAiB;QAC9C,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,oFAAoF,CAAC,CAAC;QACxG,CAAC;QACD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IAC3C,CAAC;CACF","sourcesContent":["/**\n * MqttTopicBuilder is a utility class responsible for generating MQTT topics\n * based on a standardized pattern using the package name, version, and process name.\n *\n * This centralizes all MQTT topic definitions so that changes to topic structures\n * only need to be made in one place.\n */\nexport class MqttTopicBuilder {\n private processStatusTopic: string;\n\n /**\n * Constructor for MqttTopicBuilder.\n * It validates the provided process status topic and initializes the instance.\n * @param processStatusTopic The base topic for the process status.\n * Example: \"uns-infra/packageName/version/processName/\"\n */\n constructor(processStatusTopic: string) {\n \n if (!/^uns-infra\\/[^/]+\\/[^/]+\\/[^/]+\\/$/.test(processStatusTopic)) {\n throw new Error(\"processStatusTopic must follow the pattern 'uns-infra/<packageName>/<version>/<processName>/'\");\n }\n this.processStatusTopic = processStatusTopic;\n }\n\n /**\n * Sanitize topic\n * @param name \n * @returns \n */\n public static sanitizeTopicPart(name: string): string {\n const sanitized = name\n .replace(/[^a-zA-Z0-9_-]+/g, \"-\")\n .replace(/-{2,}/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n\n return sanitized.length > 0 ? sanitized : \"uns-process\";\n }; \n \n /**\n * Returns the process status topic.\n *\n * Example: \"uns-infra/packageName/version/processName\"\n */\n public getProcessStatusTopic(): string {\n return this.processStatusTopic;\n }\n \n /**\n * Returns the topic used for publishing the active state.\n *\n * Example: \"uns-infra/packageName/version/processName/active\"\n */\n public getActiveTopic(): string {\n return this.getProcessStatusTopic() + \"active\";\n }\n \n /**\n * Returns the topic used for handover requests.\n *\n * Example: \"uns-infra/packageName/version/processName/handover\"\n */\n public getHandoverTopic(): string {\n return this.getProcessStatusTopic() + \"handover\";\n }\n \n /**\n * Returns a wildcard topic for active status messages from any process.\n * Useful for subscriptions that must capture status from multiple processes.\n *\n * Example: \"uns-infra/packageName/+/+/active\"\n */\n public getWildcardActiveTopic(): string {\n return this.getProcessStatusTopic().split('/').slice(0, 2).join('/') + '/+/+/active';\n }\n\n /**\n * Extract base topic from a full topic string.\n * This is useful for creating a topic builder from an existing topic.\n * @param fullTopic The full topic string.\n * Example: \"uns-infra/packageName/version/processName/active\"\n * @returns The base topic string.\n * Example: \"uns-infra/packageName/version/processName/\"\n */\n public static extractBaseTopic(fullTopic: string): string {\n const parts = fullTopic.split('/');\n if (parts.length < 4) {\n throw new Error(\"Invalid topic format. Expected 'uns-infra/<packageName>/<version>/<processName>/'.\");\n }\n return parts.slice(0, 4).join('/') + '/';\n }\n }\n "]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mqtt-worker-init.js","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-worker-init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,IAAI,CAAC,YAAY,IAAI,UAAU,EAAE,CAAC;IAChC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;AAC7B,CAAC","sourcesContent":["import { isMainThread, parentPort, workerData } from \"worker_threads\";\
|
|
1
|
+
{"version":3,"file":"mqtt-worker-init.js","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-worker-init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,IAAI,CAAC,YAAY,IAAI,UAAU,EAAE,CAAC;IAChC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;AAC7B,CAAC","sourcesContent":["import { isMainThread, parentPort, workerData } from \"worker_threads\";\nimport { MqttWorker } from \"./mqtt-worker.js\";\n\nif (!isMainThread && parentPort) {\n new MqttWorker(workerData);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mqtt-worker.js","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-worker.ts"],"names":[],"mappings":"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","sourcesContent":["import { IClientPublishOptions } from \"mqtt\";\
|
|
1
|
+
{"version":3,"file":"mqtt-worker.js","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-worker.ts"],"names":[],"mappings":"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","sourcesContent":["import { IClientPublishOptions } from \"mqtt\";\nimport { join } from \"path\";\nimport { parentPort } from \"worker_threads\";\n\nimport { basePath } from \"../base-path.js\";\nimport logger from \"../logger.js\";\nimport { IMqttWorkerData } from \"./mqtt-interfaces.js\";\nimport MqttProxy from \"./mqtt-proxy.js\";\nimport { ThrottledPublisher, ThrottledSubscriber } from \"./throttled-queue.js\";\n\nexport class MqttWorker {\n private mqttProxy: MqttProxy;\n protected publisher: ThrottledPublisher;\n protected subscriber: ThrottledSubscriber;\n\n constructor(workerData: IMqttWorkerData) {\n const publishThrottlingDelay = workerData.publishThrottlingDelay || 1;\n const subscribeThrottlingDelay = workerData.subscribeThrottlingDelay || 1;\n const persistToDisk = workerData.persistToDisk || false;\n const mqttHost = workerData.mqttHost;\n const instanceName = workerData.instanceNameWithSuffix;\n const mqttParameters = workerData.mqttParameters;\n const publisherActive = workerData.publisherActive;\n const subscriberActive = workerData.subscriberActive;\n\n // Initialize and start the MQTT proxy.\n this.mqttProxy = new MqttProxy(mqttHost, instanceName, mqttParameters, this);\n this.mqttProxy.start();\n\n // Set up the event listener for incoming messages from the MQTT proxy.\n this.mqttProxy.event.on(\"input\", (event) => {\n this.subscriber.enqueue(event.topic, event.message.toString());\n });\n\n // Set up the event listener for status messages from the MQTT proxy.\n this.mqttProxy.event.on(\"mqttProxyStatus\", (event) => {\n parentPort?.postMessage({\n command: \"mqttProxyStatus\",\n event: event.event,\n value: event.value,\n statusTopic: event.statusTopic,\n uom: event.uom,\n });\n });\n\n // Define the publish function to be used by the ThrottledPublisher.\n const publishFunction = async (topic: string, message: string, id: string, options?: IClientPublishOptions): Promise<void> => {\n this.mqttProxy.publish(topic, message, options).then(\n () => {\n parentPort?.postMessage({\n command: \"enqueueResult\",\n id,\n status: \"success\",\n topic,\n message,\n options,\n });\n },\n (reason: any) => {\n logger.error(`${instanceName} - Error publishing message to topic ${topic}: ${reason.message}`);\n },\n );\n };\n\n // Create an instance of ThrottledPublisher.\n this.publisher = new ThrottledPublisher(\n publishThrottlingDelay,\n publishFunction,\n persistToDisk,\n join(basePath, \"/workerQueue/\", \"throttled-publisher-queue.json\"),\n instanceName,\n publisherActive,\n );\n\n // Define the message handler for incoming messages.\n const messageHandler = async (topic: string, message: string): Promise<void> => {\n parentPort?.postMessage({\n command: \"input\",\n topic: topic,\n message: message,\n });\n };\n\n // Create an instance of ThrottledSubscriber.\n this.subscriber = new ThrottledSubscriber(\n subscribeThrottlingDelay,\n messageHandler,\n persistToDisk,\n join(basePath, \"/workerQueue/\", \"throttled-subscriber-queue.json\"),\n instanceName,\n subscriberActive,\n );\n\n // Set up the message listener for commands from the main thread.\n this.initializeMessageListener();\n }\n\n /**\n * Listen for incoming messages from the main thread and process them.\n */\n private initializeMessageListener(): void {\n parentPort?.on(\"message\", async (msg) => {\n if (msg && msg.command === \"enqueue\" && msg.id && msg.topic && msg.message !== undefined) {\n try {\n await this.publisher.enqueue(msg.topic, msg.message, msg.id, msg.options);\n } catch (error: any) {\n // Error\n }\n } else if (msg && msg.command === \"subscribeAsync\" && msg.topics) {\n this.mqttProxy.subscribeAsync(msg.topics);\n } else if (msg && msg.command === \"unsubscribeAsync\" && msg.topics) {\n this.mqttProxy.unsubscribeAsync(msg.topics);\n } else if (msg && msg.command === \"setPublisherActive\") {\n this.publisher.becomeActive({batchSize: msg?.batchSize, referenceHash: msg?.referenceHash});\n } else if (msg && msg.command === \"setPublisherPassive\") {\n const snapshot = await this.publisher.becomePassive(3);\n parentPort?.postMessage({\n command: \"handover_publisher\",\n ...snapshot\n }); \n } else if (msg && msg.command === \"setSubscriberActive\") {\n this.subscriber.becomeActive({batchSize: msg?.batchSize, referenceHash: msg?.referenceHash});\n } else if (msg && msg.command === \"setSubscriberPassive\") {\n const snapshot = await this.subscriber.becomePassive(3);\n parentPort?.postMessage({\n command: \"handover_subscriber\",\n ...snapshot\n }); \n }\n });\n }\n\n /**\n * Get the state of the publisher.\n */\n public getPublisherState(): boolean {\n return this.publisher.getState();\n }\n /**\n * Get the state of the subscriber.\n */\n public getSubscriberState(): boolean {\n return this.subscriber.getState();\n }\n\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"throttled-queue.js","sourceRoot":"","sources":["../../src/uns-mqtt/throttled-queue.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"crypto\";\r\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\r\nimport { IClientPublishOptions } from \"mqtt\";\r\nimport { join } from \"path\";\r\n\r\nimport { basePath } from \"../base-path.js\";\r\nimport logger from \"../logger.js\";\r\n\r\n/**\r\n * Abstract base class that encapsulates common functionality for managing\r\n * a throttled in‑memory queue with an optional disk persistence.\r\n */\r\nabstract class ThrottledQueue<T> {\r\n protected queue: T[] = [];\r\n protected lastProcessedItems: T[] = [];\r\n protected isProcessing = false;\r\n public delay: number;\r\n protected persistToDisk: boolean;\r\n protected persistenceFilePath: string;\r\n protected previousLoggedSize = 0;\r\n protected instanceName: string;\r\n protected active: boolean = true;\r\n private inactiveLogSent = false;\r\n\r\n constructor(delay: number, persistToDisk: boolean, instanceName: string) {\r\n this.delay = delay;\r\n this.persistToDisk = persistToDisk;\r\n this.instanceName = instanceName;\r\n\r\n if (this.persistToDisk) {\r\n this.loadQueueFromDisk();\r\n }\r\n }\r\n\r\n /**\r\n * Process the queue items one at a time with a delay between each.\r\n */\r\n protected async processQueue(): Promise<void> {\r\n if (this.isProcessing) return;\r\n this.isProcessing = true;\r\n\r\n if (!this.active) {\r\n if (!this.inactiveLogSent) {\r\n logger.info(`${this.instanceName} - Queue is not active. Exiting processQueue.`);\r\n this.inactiveLogSent = true;\r\n }\r\n this.isProcessing = false;\r\n return;\r\n }\r\n // Reset the flag when processing actually starts.\r\n this.inactiveLogSent = false;\r\n \r\n while (this.queue.length > 0) {\r\n // Check if the queue is active\r\n if (!this.active) {\r\n logger.info(`${this.instanceName} - Queue processing paused.`);\r\n this.isProcessing = false;\r\n return; // Exit the loop and stop processing\r\n }\r\n\r\n const item = this.queue.shift();\r\n if (item) {\r\n try {\r\n await this.processItem(item);\r\n // Only store 10 last processed items\r\n if (this.lastProcessedItems.length >= 10) {\r\n this.lastProcessedItems.shift();\r\n }\r\n // Store the last processed item\r\n this.lastProcessedItems.push(item);\r\n } catch (error) {\r\n // Specific error handling can be done in the subclass if needed.\r\n logger.error(`${this.instanceName} - Error processing item: ${(error as Error).message}`);\r\n }\r\n\r\n if (this.persistToDisk) {\r\n this.saveQueueToDisk();\r\n }\r\n\r\n if (this.delay > 0) {\r\n await new Promise((resolve) => setTimeout(resolve, this.delay));\r\n }\r\n\r\n this.logQueueSize();\r\n }\r\n }\r\n\r\n this.isProcessing = false;\r\n }\r\n\r\n /**\r\n * Log changes to the queue size at significant thresholds.\r\n */\r\n protected logQueueSize(): void {\r\n const className = `${this.constructor.name.includes(\"Publisher\") ? \"Publisher\" : this.constructor.name.includes(\"Subscriber\") ? \"Subscriber\" : \"Unknown\"}`;\r\n if (\r\n this.queue.length > 1\r\n && this.queue.length > this.previousLoggedSize\r\n && Math.floor(this.queue.length / 100) > Math.floor(this.previousLoggedSize / 100)\r\n ) {\r\n logger.info(`${this.instanceName} - ${className} queue size length is ${this.queue.length}.`);\r\n this.previousLoggedSize = this.queue.length;\r\n } else if (this.queue.length === 0 && this.previousLoggedSize > 0) {\r\n logger.info(`${this.instanceName} - ${className} queue is empty.`);\r\n this.previousLoggedSize = 0;\r\n }\r\n }\r\n\r\n /**\r\n * Save the current queue to disk.\r\n */\r\n protected saveQueueToDisk(): void {\r\n try {\r\n const queueData = this.queue.map((item) => this.serializeItem(item));\r\n const dir = join(this.persistenceFilePath, \"..\");\r\n if (!existsSync(dir)) {\r\n mkdirSync(dir, { recursive: true });\r\n }\r\n writeFileSync(this.persistenceFilePath, JSON.stringify(queueData, null, 2));\r\n logger.debug(`${this.instanceName} - Queue saved to disk.`);\r\n } catch (error: any) {\r\n logger.error(`${this.instanceName} - Error saving queue to disk: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * Load the queue from disk.\r\n */\r\n protected loadQueueFromDisk(): void {\r\n try {\r\n if (existsSync(this.persistenceFilePath)) {\r\n const queueData = JSON.parse(readFileSync(this.persistenceFilePath, \"utf8\"));\r\n this.queue = queueData.map((data: any) => this.deserializeItem(data));\r\n logger.info(`${this.instanceName} - Queue loaded from disk.`);\r\n }\r\n } catch (error: any) {\r\n logger.error(`${this.instanceName} - Error loading queue from disk: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * Process a single queue item.\r\n */\r\n protected abstract processItem(item: T): Promise<void>;\r\n\r\n /**\r\n * Serialize a queue item for persistence.\r\n */\r\n protected abstract serializeItem(item: T): any;\r\n\r\n /**\r\n * Deserialize persisted data into a queue item.\r\n */\r\n protected abstract deserializeItem(data: any): T;\r\n}\r\n\r\n/**\r\n * Interface representing a queued publish item.\r\n */\r\ninterface PublisherQueueItem {\r\n topic: string;\r\n message: string;\r\n id: string;\r\n options?: IClientPublishOptions;\r\n resolve: () => void;\r\n reject: (err: any) => void;\r\n}\r\n\r\n/**\r\n * ThrottledPublisher: manages a queue of outgoing publish requests,\r\n * sending one message at a time using a provided publish function.\r\n */\r\nexport class ThrottledPublisher extends ThrottledQueue<PublisherQueueItem> {\r\n private publishFunction: (topic: string, message: string, id: string, options?: IClientPublishOptions) => Promise<void>;\r\n\r\n /**\r\n * @param delay Delay between messages in milliseconds.\r\n * @param publishFunction Function to perform the actual publish.\r\n * @param persistToDisk Whether to persist the queue to disk.\r\n * @param persistenceFilePath File path for queue persistence.\r\n * @param instanceName Unique instance name for logging.\r\n */\r\n constructor(\r\n delay: number,\r\n publishFunction: (topic: string, message: string, id: string, options?: IClientPublishOptions) => Promise<void>,\r\n persistToDisk: boolean = false,\r\n persistenceFilePath: string = join(basePath, \"/publisherQueue/\", \"throttled-publisher-queue.json\"),\r\n instanceName: string,\r\n active: boolean,\r\n ) {\r\n super(delay, persistToDisk, instanceName);\r\n this.persistenceFilePath = persistenceFilePath;\r\n this.publishFunction = publishFunction;\r\n this.active = active;\r\n if (active) {\r\n logger.info(`${this.instanceName} - Publisher is active.`);\r\n } else {\r\n logger.info(`${this.instanceName} - Publisher is passive.`);\r\n }\r\n }\r\n\r\n /**\r\n * Enqueue a publish request.\r\n */\r\n public enqueue(topic: string, message: string, id: string, options?: IClientPublishOptions): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n this.queue.push({ topic, message, id, options, resolve, reject });\r\n\r\n // Trigger logging after a new message is added.\r\n this.logQueueSize(); \r\n\r\n if (this.persistToDisk) {\r\n this.saveQueueToDisk();\r\n }\r\n\r\n if (this.active) {\r\n this.processQueue();\r\n }\r\n });\r\n }\r\n\r\n private computeHashForBatch(messages: any[]): string {\r\n const data = JSON.stringify(messages);\r\n return createHash(\"sha256\").update(data).digest(\"hex\");\r\n }\r\n\r\n /**\r\n * Switch the publisher to a passive state and return a snapshot\r\n */\r\n public becomeActive(snapshot: { referenceHash: string; batchSize: number }): void {\r\n // If snapshot is empty (batchSize is zero), start processing from the beginning.\r\n if (snapshot.batchSize === 0 || snapshot.batchSize === undefined || snapshot.referenceHash === undefined) {\r\n this.active = true;\r\n logger.info(`${this.instanceName} - Publisher became active.`);\r\n this.processQueue();\r\n return;\r\n }\r\n\r\n const { referenceHash, batchSize } = snapshot;\r\n let resumeIndex = -1;\r\n\r\n // Use batchSize as the window length.\r\n for (let i = 0; i <= this.queue.length - batchSize; i++) {\r\n const currentBatch = this.queue.slice(i, i + batchSize);\r\n const currentHash = this.computeHashForBatch(currentBatch);\r\n if (currentHash === referenceHash) {\r\n resumeIndex = i + batchSize; // resume immediately after the matched batch\r\n break;\r\n }\r\n }\r\n\r\n if (resumeIndex !== -1) {\r\n // Adjust the queue so that processing resumes after the matching batch.\r\n this.queue = this.queue.slice(resumeIndex);\r\n logger.info(`${this.instanceName} - Publisher resumed from the matched snapshot position.`);\r\n } else if (this.queue.length > 0) {\r\n // Log info message and process the entire queue if no match is found.\r\n logger.info(`${this.instanceName} - No matching batch found during resume; processing the entire publisher's queue.`);\r\n }\r\n\r\n this.active = true;\r\n logger.info(`${this.instanceName} - Publisher became active.`);\r\n this.processQueue();\r\n }\r\n\r\n /**\r\n * Switch the publisher to a passive state and return a snapshot\r\n */\r\n public async becomePassive(n: number): Promise<{ referenceHash: string; batchSize: number; }> {\r\n this.active = false;\r\n logger.info(`${this.instanceName} - Publisher became passive.`);\r\n const batch = this.queue.slice(-n);\r\n const batchSize = batch.length;\r\n const referenceHash = this.computeHashForBatch(batch);\r\n if (batchSize > 0) {\r\n logger.info(`${this.instanceName} - Publisher batch reference hash: ${referenceHash}, size: ${batchSize}`);\r\n }\r\n return { referenceHash, batchSize };\r\n }\r\n\r\n public getState(): boolean {\r\n return this.active;\r\n }\r\n\r\n /**\r\n * Process a single publish request.\r\n */\r\n protected async processItem(item: PublisherQueueItem): Promise<void> {\r\n try {\r\n await this.publishFunction(item.topic, item.message, item.id, item.options);\r\n item.resolve();\r\n } catch (error) {\r\n item.reject(error);\r\n }\r\n }\r\n\r\n /**\r\n * Serialize a publish request for persistence.\r\n */\r\n protected serializeItem(item: PublisherQueueItem): any {\r\n return {\r\n topic: item.topic,\r\n message: item.message,\r\n id: item.id,\r\n options: item.options,\r\n };\r\n }\r\n\r\n /**\r\n * Deserialize persisted data into a publish request.\r\n */\r\n protected deserializeItem(data: any): PublisherQueueItem {\r\n return {\r\n topic: data.topic,\r\n message: data.message,\r\n id: data.id,\r\n options: data.options,\r\n resolve: () => {},\r\n reject: (err: any) => logger.error(`${this.instanceName} - Error processing queued publish item: ${err.message}`),\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Interface representing a queued subscribe item.\r\n */\r\ninterface SubscriberQueueItem {\r\n topic: string;\r\n message: string;\r\n timestamp: number;\r\n}\r\n\r\n/**\r\n * ThrottledSubscriber: manages a queue of incoming messages and processes\r\n * them one at a time using a provided message handler.\r\n */\r\nexport class ThrottledSubscriber extends ThrottledQueue<SubscriberQueueItem> {\r\n private messageHandler: (topic: string, message: string) => Promise<void>;\r\n\r\n /**\r\n * @param delay Delay between processing messages in milliseconds.\r\n * @param messageHandler Function to process incoming messages.\r\n * @param persistToDisk Whether to persist the queue to disk.\r\n * @param persistenceFilePath File path for queue persistence.\r\n * @param instanceName Unique instance name for logging.\r\n */\r\n constructor(\r\n delay: number,\r\n messageHandler: (topic: string, message: string) => Promise<void>,\r\n persistToDisk: boolean = false,\r\n persistenceFilePath: string = join(basePath, \"/subscriberQueue/\", \"throttled-subscriber-queue.json\"),\r\n instanceName: string,\r\n active: boolean,\r\n ) {\r\n super(delay, persistToDisk, instanceName);\r\n this.persistenceFilePath = persistenceFilePath;\r\n this.messageHandler = messageHandler;\r\n this.active = active;\r\n if (active) {\r\n logger.info(`${this.instanceName} - Subscriber is active.`);\r\n } else {\r\n logger.info(`${this.instanceName} - Subscriber is passive.`);\r\n }\r\n }\r\n\r\n /**\r\n * Enqueue subscribe messages for processing.\r\n */\r\n public enqueue(topic: string, message: string): void {\r\n this.queue.push({ topic, message, timestamp: Date.now() });\r\n \r\n // Trigger logging after a new message is added.\r\n this.logQueueSize();\r\n \r\n if (this.persistToDisk) {\r\n this.saveQueueToDisk();\r\n }\r\n\r\n if (this.active) {\r\n this.processQueue();\r\n }\r\n }\r\n\r\n /**\r\n * Process a single subscribe message.\r\n */\r\n protected async processItem(item: SubscriberQueueItem): Promise<void> {\r\n await this.messageHandler(item.topic, item.message);\r\n }\r\n\r\n /**\r\n * Serialize a subscribe message for persistence.\r\n */\r\n protected serializeItem(item: SubscriberQueueItem): any {\r\n return {\r\n message: item.message,\r\n };\r\n }\r\n\r\n /**\r\n * Deserialize persisted data into a subscribe message.\r\n */\r\n protected deserializeItem(data: any): SubscriberQueueItem {\r\n return {\r\n topic: data.topic,\r\n message: data.message,\r\n timestamp: data.timestamp,\r\n };\r\n }\r\n\r\n /**\r\n * Get the current state of the subscriber (active or passive).\r\n */\r\n public getState(): boolean {\r\n return this.active;\r\n }\r\n\r\n /**\r\n * Computes a SHA‑256 hash for a given batch of subscriber items.\r\n */\r\n private computeHashForBatch(messages: SubscriberQueueItem[]): string {\r\n const data = JSON.stringify(messages.map((item) => this.serializeItem(item)));\r\n return createHash(\"sha256\").update(data).digest(\"hex\");\r\n }\r\n\r\n /**\r\n * Switch the subscriber to a passive state and return a snapshot.\r\n */\r\n public async becomePassive(n: number): Promise<{ referenceHash: string; batchSize: number; }> {\r\n this.active = false;\r\n logger.info(`${this.instanceName} - Subscriber is passive.`);\r\n const batch = this.lastProcessedItems.slice(-n);\r\n const batchSize = batch.length;\r\n const referenceHash = this.computeHashForBatch(batch);\r\n if (batchSize > 0) {\r\n logger.info(`${this.instanceName} - Subscriber batch reference hash: ${referenceHash}, size: ${batchSize}`);\r\n }\r\n return { referenceHash, batchSize };\r\n }\r\n\r\n /**\r\n * Switch the subscriber to an active state and resume processing.\r\n */\r\n public becomeActive(snapshot: { referenceHash: string; batchSize: number }): void {\r\n // If snapshot is empty (batchSize is zero), start processing from the beginning.\r\n if (snapshot.batchSize === 0 || snapshot.batchSize === undefined || snapshot.referenceHash === undefined) {\r\n this.active = true;\r\n logger.info(`${this.instanceName} - Subscriber became active.`); \r\n this.processQueue();\r\n return;\r\n }\r\n\r\n const { referenceHash, batchSize } = snapshot;\r\n let resumeIndex = -1;\r\n\r\n // Use batchSize as the window length.\r\n for (let i = 0; i <= this.queue.length - batchSize; i++) {\r\n const currentBatch = this.queue.slice(i, i + batchSize);\r\n const currentHash = this.computeHashForBatch(currentBatch);\r\n if (currentHash === referenceHash) {\r\n resumeIndex = i + batchSize; // resume immediately after the matched batch\r\n break;\r\n }\r\n }\r\n\r\n if (resumeIndex !== -1) {\r\n // Adjust the queue so that processing resumes after the matching batch.\r\n const queueSlice = this.queue.slice(resumeIndex); \r\n this.queue = queueSlice;\r\n logger.info(`${this.instanceName} - Subscriber resumed from the matched snapshot position.`);\r\n } else if (this.queue.length > 0) {\r\n // Log info message and process the entire queue if no match is found.\r\n logger.info(`${this.instanceName} - No matching batch found during resume; processing the entire subscriber's queue.`);\r\n }\r\n\r\n this.active = true;\r\n logger.info(`${this.instanceName} - Subscriber became active.`); \r\n this.processQueue();\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"throttled-queue.js","sourceRoot":"","sources":["../../src/uns-mqtt/throttled-queue.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { IClientPublishOptions } from \"mqtt\";\nimport { join } from \"path\";\n\nimport { basePath } from \"../base-path.js\";\nimport logger from \"../logger.js\";\n\n/**\n * Abstract base class that encapsulates common functionality for managing\n * a throttled in‑memory queue with an optional disk persistence.\n */\nabstract class ThrottledQueue<T> {\n protected queue: T[] = [];\n protected lastProcessedItems: T[] = [];\n protected isProcessing = false;\n public delay: number;\n protected persistToDisk: boolean;\n protected persistenceFilePath: string;\n protected previousLoggedSize = 0;\n protected instanceName: string;\n protected active: boolean = true;\n private inactiveLogSent = false;\n\n constructor(delay: number, persistToDisk: boolean, instanceName: string) {\n this.delay = delay;\n this.persistToDisk = persistToDisk;\n this.instanceName = instanceName;\n\n if (this.persistToDisk) {\n this.loadQueueFromDisk();\n }\n }\n\n /**\n * Process the queue items one at a time with a delay between each.\n */\n protected async processQueue(): Promise<void> {\n if (this.isProcessing) return;\n this.isProcessing = true;\n\n if (!this.active) {\n if (!this.inactiveLogSent) {\n logger.info(`${this.instanceName} - Queue is not active. Exiting processQueue.`);\n this.inactiveLogSent = true;\n }\n this.isProcessing = false;\n return;\n }\n // Reset the flag when processing actually starts.\n this.inactiveLogSent = false;\n \n while (this.queue.length > 0) {\n // Check if the queue is active\n if (!this.active) {\n logger.info(`${this.instanceName} - Queue processing paused.`);\n this.isProcessing = false;\n return; // Exit the loop and stop processing\n }\n\n const item = this.queue.shift();\n if (item) {\n try {\n await this.processItem(item);\n // Only store 10 last processed items\n if (this.lastProcessedItems.length >= 10) {\n this.lastProcessedItems.shift();\n }\n // Store the last processed item\n this.lastProcessedItems.push(item);\n } catch (error) {\n // Specific error handling can be done in the subclass if needed.\n logger.error(`${this.instanceName} - Error processing item: ${(error as Error).message}`);\n }\n\n if (this.persistToDisk) {\n this.saveQueueToDisk();\n }\n\n if (this.delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, this.delay));\n }\n\n this.logQueueSize();\n }\n }\n\n this.isProcessing = false;\n }\n\n /**\n * Log changes to the queue size at significant thresholds.\n */\n protected logQueueSize(): void {\n const className = `${this.constructor.name.includes(\"Publisher\") ? \"Publisher\" : this.constructor.name.includes(\"Subscriber\") ? \"Subscriber\" : \"Unknown\"}`;\n if (\n this.queue.length > 1\n && this.queue.length > this.previousLoggedSize\n && Math.floor(this.queue.length / 100) > Math.floor(this.previousLoggedSize / 100)\n ) {\n logger.info(`${this.instanceName} - ${className} queue size length is ${this.queue.length}.`);\n this.previousLoggedSize = this.queue.length;\n } else if (this.queue.length === 0 && this.previousLoggedSize > 0) {\n logger.info(`${this.instanceName} - ${className} queue is empty.`);\n this.previousLoggedSize = 0;\n }\n }\n\n /**\n * Save the current queue to disk.\n */\n protected saveQueueToDisk(): void {\n try {\n const queueData = this.queue.map((item) => this.serializeItem(item));\n const dir = join(this.persistenceFilePath, \"..\");\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(this.persistenceFilePath, JSON.stringify(queueData, null, 2));\n logger.debug(`${this.instanceName} - Queue saved to disk.`);\n } catch (error: any) {\n logger.error(`${this.instanceName} - Error saving queue to disk: ${error.message}`);\n }\n }\n\n /**\n * Load the queue from disk.\n */\n protected loadQueueFromDisk(): void {\n try {\n if (existsSync(this.persistenceFilePath)) {\n const queueData = JSON.parse(readFileSync(this.persistenceFilePath, \"utf8\"));\n this.queue = queueData.map((data: any) => this.deserializeItem(data));\n logger.info(`${this.instanceName} - Queue loaded from disk.`);\n }\n } catch (error: any) {\n logger.error(`${this.instanceName} - Error loading queue from disk: ${error.message}`);\n }\n }\n\n /**\n * Process a single queue item.\n */\n protected abstract processItem(item: T): Promise<void>;\n\n /**\n * Serialize a queue item for persistence.\n */\n protected abstract serializeItem(item: T): any;\n\n /**\n * Deserialize persisted data into a queue item.\n */\n protected abstract deserializeItem(data: any): T;\n}\n\n/**\n * Interface representing a queued publish item.\n */\ninterface PublisherQueueItem {\n topic: string;\n message: string;\n id: string;\n options?: IClientPublishOptions;\n resolve: () => void;\n reject: (err: any) => void;\n}\n\n/**\n * ThrottledPublisher: manages a queue of outgoing publish requests,\n * sending one message at a time using a provided publish function.\n */\nexport class ThrottledPublisher extends ThrottledQueue<PublisherQueueItem> {\n private publishFunction: (topic: string, message: string, id: string, options?: IClientPublishOptions) => Promise<void>;\n\n /**\n * @param delay Delay between messages in milliseconds.\n * @param publishFunction Function to perform the actual publish.\n * @param persistToDisk Whether to persist the queue to disk.\n * @param persistenceFilePath File path for queue persistence.\n * @param instanceName Unique instance name for logging.\n */\n constructor(\n delay: number,\n publishFunction: (topic: string, message: string, id: string, options?: IClientPublishOptions) => Promise<void>,\n persistToDisk: boolean = false,\n persistenceFilePath: string = join(basePath, \"/publisherQueue/\", \"throttled-publisher-queue.json\"),\n instanceName: string,\n active: boolean,\n ) {\n super(delay, persistToDisk, instanceName);\n this.persistenceFilePath = persistenceFilePath;\n this.publishFunction = publishFunction;\n this.active = active;\n if (active) {\n logger.info(`${this.instanceName} - Publisher is active.`);\n } else {\n logger.info(`${this.instanceName} - Publisher is passive.`);\n }\n }\n\n /**\n * Enqueue a publish request.\n */\n public enqueue(topic: string, message: string, id: string, options?: IClientPublishOptions): Promise<void> {\n return new Promise((resolve, reject) => {\n this.queue.push({ topic, message, id, options, resolve, reject });\n\n // Trigger logging after a new message is added.\n this.logQueueSize(); \n\n if (this.persistToDisk) {\n this.saveQueueToDisk();\n }\n\n if (this.active) {\n this.processQueue();\n }\n });\n }\n\n private computeHashForBatch(messages: any[]): string {\n const data = JSON.stringify(messages);\n return createHash(\"sha256\").update(data).digest(\"hex\");\n }\n\n /**\n * Switch the publisher to a passive state and return a snapshot\n */\n public becomeActive(snapshot: { referenceHash: string; batchSize: number }): void {\n // If snapshot is empty (batchSize is zero), start processing from the beginning.\n if (snapshot.batchSize === 0 || snapshot.batchSize === undefined || snapshot.referenceHash === undefined) {\n this.active = true;\n logger.info(`${this.instanceName} - Publisher became active.`);\n this.processQueue();\n return;\n }\n\n const { referenceHash, batchSize } = snapshot;\n let resumeIndex = -1;\n\n // Use batchSize as the window length.\n for (let i = 0; i <= this.queue.length - batchSize; i++) {\n const currentBatch = this.queue.slice(i, i + batchSize);\n const currentHash = this.computeHashForBatch(currentBatch);\n if (currentHash === referenceHash) {\n resumeIndex = i + batchSize; // resume immediately after the matched batch\n break;\n }\n }\n\n if (resumeIndex !== -1) {\n // Adjust the queue so that processing resumes after the matching batch.\n this.queue = this.queue.slice(resumeIndex);\n logger.info(`${this.instanceName} - Publisher resumed from the matched snapshot position.`);\n } else if (this.queue.length > 0) {\n // Log info message and process the entire queue if no match is found.\n logger.info(`${this.instanceName} - No matching batch found during resume; processing the entire publisher's queue.`);\n }\n\n this.active = true;\n logger.info(`${this.instanceName} - Publisher became active.`);\n this.processQueue();\n }\n\n /**\n * Switch the publisher to a passive state and return a snapshot\n */\n public async becomePassive(n: number): Promise<{ referenceHash: string; batchSize: number; }> {\n this.active = false;\n logger.info(`${this.instanceName} - Publisher became passive.`);\n const batch = this.queue.slice(-n);\n const batchSize = batch.length;\n const referenceHash = this.computeHashForBatch(batch);\n if (batchSize > 0) {\n logger.info(`${this.instanceName} - Publisher batch reference hash: ${referenceHash}, size: ${batchSize}`);\n }\n return { referenceHash, batchSize };\n }\n\n public getState(): boolean {\n return this.active;\n }\n\n /**\n * Process a single publish request.\n */\n protected async processItem(item: PublisherQueueItem): Promise<void> {\n try {\n await this.publishFunction(item.topic, item.message, item.id, item.options);\n item.resolve();\n } catch (error) {\n item.reject(error);\n }\n }\n\n /**\n * Serialize a publish request for persistence.\n */\n protected serializeItem(item: PublisherQueueItem): any {\n return {\n topic: item.topic,\n message: item.message,\n id: item.id,\n options: item.options,\n };\n }\n\n /**\n * Deserialize persisted data into a publish request.\n */\n protected deserializeItem(data: any): PublisherQueueItem {\n return {\n topic: data.topic,\n message: data.message,\n id: data.id,\n options: data.options,\n resolve: () => {},\n reject: (err: any) => logger.error(`${this.instanceName} - Error processing queued publish item: ${err.message}`),\n };\n }\n}\n\n/**\n * Interface representing a queued subscribe item.\n */\ninterface SubscriberQueueItem {\n topic: string;\n message: string;\n timestamp: number;\n}\n\n/**\n * ThrottledSubscriber: manages a queue of incoming messages and processes\n * them one at a time using a provided message handler.\n */\nexport class ThrottledSubscriber extends ThrottledQueue<SubscriberQueueItem> {\n private messageHandler: (topic: string, message: string) => Promise<void>;\n\n /**\n * @param delay Delay between processing messages in milliseconds.\n * @param messageHandler Function to process incoming messages.\n * @param persistToDisk Whether to persist the queue to disk.\n * @param persistenceFilePath File path for queue persistence.\n * @param instanceName Unique instance name for logging.\n */\n constructor(\n delay: number,\n messageHandler: (topic: string, message: string) => Promise<void>,\n persistToDisk: boolean = false,\n persistenceFilePath: string = join(basePath, \"/subscriberQueue/\", \"throttled-subscriber-queue.json\"),\n instanceName: string,\n active: boolean,\n ) {\n super(delay, persistToDisk, instanceName);\n this.persistenceFilePath = persistenceFilePath;\n this.messageHandler = messageHandler;\n this.active = active;\n if (active) {\n logger.info(`${this.instanceName} - Subscriber is active.`);\n } else {\n logger.info(`${this.instanceName} - Subscriber is passive.`);\n }\n }\n\n /**\n * Enqueue subscribe messages for processing.\n */\n public enqueue(topic: string, message: string): void {\n this.queue.push({ topic, message, timestamp: Date.now() });\n \n // Trigger logging after a new message is added.\n this.logQueueSize();\n \n if (this.persistToDisk) {\n this.saveQueueToDisk();\n }\n\n if (this.active) {\n this.processQueue();\n }\n }\n\n /**\n * Process a single subscribe message.\n */\n protected async processItem(item: SubscriberQueueItem): Promise<void> {\n await this.messageHandler(item.topic, item.message);\n }\n\n /**\n * Serialize a subscribe message for persistence.\n */\n protected serializeItem(item: SubscriberQueueItem): any {\n return {\n message: item.message,\n };\n }\n\n /**\n * Deserialize persisted data into a subscribe message.\n */\n protected deserializeItem(data: any): SubscriberQueueItem {\n return {\n topic: data.topic,\n message: data.message,\n timestamp: data.timestamp,\n };\n }\n\n /**\n * Get the current state of the subscriber (active or passive).\n */\n public getState(): boolean {\n return this.active;\n }\n\n /**\n * Computes a SHA‑256 hash for a given batch of subscriber items.\n */\n private computeHashForBatch(messages: SubscriberQueueItem[]): string {\n const data = JSON.stringify(messages.map((item) => this.serializeItem(item)));\n return createHash(\"sha256\").update(data).digest(\"hex\");\n }\n\n /**\n * Switch the subscriber to a passive state and return a snapshot.\n */\n public async becomePassive(n: number): Promise<{ referenceHash: string; batchSize: number; }> {\n this.active = false;\n logger.info(`${this.instanceName} - Subscriber is passive.`);\n const batch = this.lastProcessedItems.slice(-n);\n const batchSize = batch.length;\n const referenceHash = this.computeHashForBatch(batch);\n if (batchSize > 0) {\n logger.info(`${this.instanceName} - Subscriber batch reference hash: ${referenceHash}, size: ${batchSize}`);\n }\n return { referenceHash, batchSize };\n }\n\n /**\n * Switch the subscriber to an active state and resume processing.\n */\n public becomeActive(snapshot: { referenceHash: string; batchSize: number }): void {\n // If snapshot is empty (batchSize is zero), start processing from the beginning.\n if (snapshot.batchSize === 0 || snapshot.batchSize === undefined || snapshot.referenceHash === undefined) {\n this.active = true;\n logger.info(`${this.instanceName} - Subscriber became active.`); \n this.processQueue();\n return;\n }\n\n const { referenceHash, batchSize } = snapshot;\n let resumeIndex = -1;\n\n // Use batchSize as the window length.\n for (let i = 0; i <= this.queue.length - batchSize; i++) {\n const currentBatch = this.queue.slice(i, i + batchSize);\n const currentHash = this.computeHashForBatch(currentBatch);\n if (currentHash === referenceHash) {\n resumeIndex = i + batchSize; // resume immediately after the matched batch\n break;\n }\n }\n\n if (resumeIndex !== -1) {\n // Adjust the queue so that processing resumes after the matching batch.\n const queueSlice = this.queue.slice(resumeIndex); \n this.queue = queueSlice;\n logger.info(`${this.instanceName} - Subscriber resumed from the matched snapshot position.`);\n } else if (this.queue.length > 0) {\n // Log info message and process the entire queue if no match is found.\n logger.info(`${this.instanceName} - No matching batch found during resume; processing the entire subscriber's queue.`);\n }\n\n this.active = true;\n logger.info(`${this.instanceName} - Subscriber became active.`); \n this.processQueue();\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uns-mqtt-proxy.js","sourceRoot":"","sources":["../../src/uns-mqtt/uns-mqtt-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync } from \"fs\";\r\nimport { IClientPublishOptions } from \"mqtt\";\r\nimport * as path from \"path\";\r\nimport { Worker } from \"worker_threads\";\r\nimport { fileURLToPath } from \"url\";\r\nimport { basePath } from \"../base-path.js\";\r\nimport logger from \"../logger.js\";\r\nimport { IMqttMessage, IUnsPacket, IUnsParameters, UnsEvents, ValueType } from \"../uns/uns-interfaces.js\";\r\nimport { MeasurementUnit } from \"../uns/uns-measurements.js\";\r\nimport { UnsPacket } from \"../uns/uns-packet.js\";\r\nimport { IMqttParameters, IMqttWorkerData } from \"./mqtt-interfaces.js\";\r\nimport { MqttTopicBuilder } from \"./mqtt-topic-builder.js\";\r\nimport UnsProxy from \"../uns/uns-proxy.js\";\r\nimport { UnsAttributeType } from \"../graphql/schema.js\";\r\n\r\nconst packageJsonPath = path.join(basePath, \"package.json\");\r\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf8\"));\r\n\r\nconst moduleDirectory = path.dirname(fileURLToPath(import.meta.url));\r\nconst packageRoot = path.resolve(moduleDirectory, \"..\", \"..\");\r\nconst workerScriptPath = path.join(packageRoot, \"dist/uns-mqtt/mqtt-worker-init.js\");\r\n\r\nexport enum MessageMode {\r\n Raw = 'raw', // Send only the original message\r\n Delta = 'delta', // Send only the delta message\r\n Both = 'both' // Send both the original and delta messages\r\n}\r\n\r\nexport default class UnsMqttProxy extends UnsProxy {\r\n private lastValues: Map<string, { value: ValueType; uom: string; timestamp: Date }> = new Map();\r\n private worker: Worker;\r\n private pendingEnqueues: Map<string, { resolve: () => void; reject: (reason?: any) => void }> = new Map();\r\n private unsParameters: IUnsParameters;\r\n protected processStatusTopic: string;\r\n public instanceName: string;\r\n private currentSequenceId: Map<string, number> = new Map();\r\n private topicBuilder: MqttTopicBuilder;\r\n\r\n constructor(\r\n mqttHost: string,\r\n processName: string,\r\n instanceName: string,\r\n unsParameters?: IUnsParameters,\r\n publisherActive: boolean = false,\r\n subscriberActive: boolean = false\r\n ) {\r\n super();\r\n this.instanceName = instanceName;\r\n // Create the topic builder using packageJson values and the processName.\r\n this.topicBuilder = new MqttTopicBuilder(`uns-infra/${MqttTopicBuilder.sanitizeTopicPart(packageJson.name)}/${MqttTopicBuilder.sanitizeTopicPart(packageJson.version)}/${MqttTopicBuilder.sanitizeTopicPart(processName)}/`);\r\n\r\n // Generate the processStatusTopic using the builder.\r\n this.processStatusTopic = this.topicBuilder.getProcessStatusTopic();\r\n // Derive the instanceStatusTopic by appending the instance name.\r\n this.instanceStatusTopic = this.processStatusTopic + instanceName + \"/\";\r\n\r\n // Concatenate processName with instanceName for the worker identification.\r\n this.instanceNameWithSuffix = `${processName}-${instanceName}`;\r\n \r\n const mqttParameters: IMqttParameters = {\r\n mqttSubToTopics: unsParameters?.mqttSubToTopics ?? [],\r\n username: unsParameters?.username ?? \"\",\r\n password: unsParameters?.password ?? \"\",\r\n mqttSSL: unsParameters?.mqttSSL ?? false,\r\n statusTopic: this.instanceStatusTopic,\r\n };\r\n this.unsParameters = unsParameters ?? {};\r\n this.startQueueWorker(mqttHost, this.instanceNameWithSuffix, mqttParameters, publisherActive, subscriberActive);\r\n }\r\n\r\n /**\r\n * Starts a worker thread to process the throttled publish queue.\r\n */\r\n private startQueueWorker(\r\n mqttHost: string,\r\n instanceNameWithSuffix: string,\r\n mqttParameters: IMqttParameters,\r\n publisherActive: boolean,\r\n subscriberActive: boolean\r\n ): void {\r\n const workerData: IMqttWorkerData = {\r\n publishThrottlingDelay: this.unsParameters.publishThrottlingDelay ?? 1,\r\n subscribeThrottlingDelay: this.unsParameters.subscribeThrottlingDelay ?? 1,\r\n persistToDisk: false,\r\n mqttHost: mqttHost,\r\n instanceNameWithSuffix: instanceNameWithSuffix,\r\n mqttParameters: mqttParameters,\r\n publisherActive,\r\n subscriberActive\r\n };\r\n\r\n this.worker = new Worker(workerScriptPath, { workerData });\r\n\r\n this.worker.on(\"message\", (msg) => {\r\n if (msg && msg.command === \"enqueueResult\" && msg.id) {\r\n const pending = this.pendingEnqueues.get(msg.id);\r\n if (pending) {\r\n if (msg.status === \"success\" && msg.topic && msg.message) {\r\n pending.resolve();\r\n } else {\r\n pending.reject(new Error(msg.error));\r\n }\r\n this.pendingEnqueues.delete(msg.id);\r\n }\r\n } else if (msg && msg.command === \"input\") {\r\n this.event.emit(\"input\", { topic: msg.topic, message: msg.message.toString(), packet: msg.packet });\r\n } else if (msg && (msg.command === \"handover_subscriber\" || msg.command === \"handover_publisher\")) {\r\n this.event.emit(\"mqttWorker\", { command: msg.command, batchSize: msg.batchSize, referenceHash: msg.referenceHash, instanceName: this.instanceName });\r\n } else if (msg && msg.command === \"mqttProxyStatus\") {\r\n this.event.emit(\"mqttProxyStatus\", { event: msg.event, value: msg.value, uom: msg.uom, statusTopic: msg.statusTopic });\r\n }\r\n });\r\n\r\n this.worker.on(\"error\", (err) => {\r\n logger.error(\"Error in worker:\", err);\r\n });\r\n\r\n this.worker.on(\"exit\", (code) => {\r\n if (code !== 0) {\r\n logger.error(`Worker exited with code ${code}`);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Enqueues a message to the worker queue.\r\n *\r\n * @param topic - The topic to which the message belongs.\r\n * @param message - The message to be enqueued.\r\n * @param options - Optional publish options.\r\n * @returns A promise that resolves when the message is successfully enqueued.\r\n */\r\n private async enqueueMessageToWorkerQueue(topic: string, message: string, options?: IClientPublishOptions): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n // const id: string = String(this.currentSequenceId.get(topic) ?? 0);\r\n const id = `${Date.now()}-${Math.random()}`;\r\n this.pendingEnqueues.set(id, { resolve, reject });\r\n this.worker.postMessage({ command: \"enqueue\", id, topic, message, options });\r\n });\r\n }\r\n\r\n /**\r\n * Sets the publisher active state.\r\n *\r\n * @param batchSize - Optional batch size.\r\n * @param referenceHash - Optional reference hash.\r\n */\r\n public setPublisherActive(batchSize?: number, referenceHash?: string): void {\r\n this.worker.postMessage({ command: \"setPublisherActive\", batchSize, referenceHash });\r\n }\r\n\r\n /**\r\n * Sets the publisher to passive mode.\r\n * @returns A promise that resolves when the publisher is set to passive.\r\n */\r\n public setPublisherPassive(): Promise<UnsEvents[\"mqttWorker\"]> {\r\n this.worker.postMessage({ command: \"setPublisherPassive\"});\r\n return new Promise((resolve) => {\r\n this.event.on(\"mqttWorker\", (msg: UnsEvents[\"mqttWorker\"]) => {\r\n if (msg.command === \"handover_publisher\") {\r\n logger.info(`${this.instanceNameWithSuffix} - Publisher set to passive.`);\r\n resolve(msg);\r\n }\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Sets the subscriber active state.\r\n *\r\n * @param batchSize - Optional batch size.\r\n * @param referenceHash - Optional reference hash.\r\n */\r\n public setSubscriberActive(batchSize?: number, referenceHash?: string): void {\r\n this.worker.postMessage({ command: \"setSubscriberActive\", batchSize, referenceHash });\r\n }\r\n\r\n /**\r\n * Sets the subscriber to passive mode.\r\n * @returns A promise that resolves when the subscriber is set to passive.\r\n */\r\n public setSubscriberPassive(): Promise<UnsEvents[\"mqttWorker\"]> {\r\n this.worker.postMessage({ command: \"setSubscriberPassive\"});\r\n return new Promise((resolve) => {\r\n this.event.on(\"mqttWorker\", (msg: UnsEvents[\"mqttWorker\"]) => {\r\n if (msg.command === \"handover_subscriber\") {\r\n logger.info(`${this.instanceNameWithSuffix} - Publisher set to passive.`);\r\n resolve(msg);\r\n }\r\n });\r\n });\r\n }\r\n\r\n\r\n /**\r\n * Sets the subscriber to passive mode and allows the publisher to run\r\n * until the queue is empty (all messages are processed).\r\n */\r\n public async setSubscriberPassiveAndDrainQueue(): Promise<UnsEvents[\"mqttWorker\"]> {\r\n return new Promise(async (resolve) => {\r\n const mqttWorkerData = await this.setSubscriberPassive();\r\n while (this.pendingEnqueues.size > 0) {\r\n await new Promise((resolve) => setTimeout(resolve, 100)); // Poll every 100ms\r\n }\r\n logger.info(`${this.instanceNameWithSuffix} - Subscriber set to passive and queue drained.`);\r\n resolve(mqttWorkerData);\r\n });\r\n }\r\n\r\n /**\r\n * Processes and publishes MQTT messages based on the selected message mode.\r\n *\r\n * @param mqttMessage - The MQTT message object.\r\n * @param mode - The message mode (Raw, Delta, or Both).\r\n */\r\n public publishMqttMessage(mqttMessage: IMqttMessage | null, mode: MessageMode = MessageMode.Raw) {\r\n if (mqttMessage) {\r\n if (mqttMessage.packet) {\r\n const time = UnsPacket.formatToISO8601(new Date());\r\n switch (mode) {\r\n case MessageMode.Raw: {\r\n this.processAndEnqueueMessage(mqttMessage, time, false);\r\n break;\r\n }\r\n case MessageMode.Delta: {\r\n const deltaMessage = { ...mqttMessage };\r\n deltaMessage.attribute = `${mqttMessage.attribute}-delta`;\r\n deltaMessage.description = `${mqttMessage.description} (delta)`;\r\n this.processAndEnqueueMessage(deltaMessage, time, true);\r\n break;\r\n }\r\n case MessageMode.Both: {\r\n this.processAndEnqueueMessage(mqttMessage, time, false);\r\n const deltaMessageBoth = { ...mqttMessage };\r\n deltaMessageBoth.attribute = `${mqttMessage.attribute}-delta`;\r\n deltaMessageBoth.description = `${mqttMessage.description} (delta)`;\r\n this.processAndEnqueueMessage(deltaMessageBoth, time, true);\r\n break;\r\n }\r\n } \r\n } else {\r\n logger.error(`${this.instanceNameWithSuffix} - Error publishing mqtt message: mqttMessage.packet must be defined.`);\r\n }\r\n } else {\r\n logger.error(`${this.instanceNameWithSuffix} - Error publishing mqtt message: mqttMessage must be defined.`);\r\n }\r\n }\r\n\r\n /**\r\n * Publishes a message to a specified topic.\r\n *\r\n * @param topic - The MQTT topic.\r\n * @param message - The message to publish.\r\n * @returns A promise that resolves when enqueued.\r\n */\r\n public publishMessage(topic: string, message: string): Promise<void> {\r\n return this.enqueueMessageToWorkerQueue(topic, message);\r\n }\r\n\r\n /**\r\n * Parses an MQTT packet from a JSON string.\r\n *\r\n * @param mqttPacket - The MQTT packet string.\r\n * @returns A parsed IUnsPacket object or null.\r\n */\r\n public parseMqttPacket(mqttPacket: string): IUnsPacket | null {\r\n return UnsPacket.parseMqttPacket(mqttPacket, this.instanceNameWithSuffix);\r\n }\r\n\r\n /**\r\n * Subscribes asynchronously to one or more topics.\r\n *\r\n * @param topics - A topic or list of topics.\r\n */\r\n public subscribeAsync(topics: string | string[]): void {\r\n this.worker.postMessage({ command: \"subscribeAsync\", topics });\r\n }\r\n\r\n /**\r\n * Unsubscribes asynchronously from the given topics.\r\n *\r\n * @param topics - A list of topics.\r\n */\r\n public unsubscribeAsync(topics: string[]): void {\r\n this.worker.postMessage({ command: \"unsubscribeAsync\", topics });\r\n }\r\n\r\n /**\r\n * Processes and enqueues a message to the worker queue, including handling\r\n * sequencing, value differences, and tracking of unique topics.\r\n *\r\n * @param msg - The MQTT message to process.\r\n * @param time - The timestamp.\r\n * @param valueIsCumulative - Whether the value is cumulative.\r\n */\r\n private async processAndEnqueueMessage(msg: IMqttMessage, time: string, valueIsCumulative: boolean = false): Promise<void> {\r\n try {\r\n const attributeType =\r\n msg.packet.message.data ? UnsAttributeType.Data :\r\n msg.packet.message.event ? UnsAttributeType.Event :\r\n msg.packet.message.table ? UnsAttributeType.Table : null;\r\n \r\n let dataGroup = \"\";\r\n if (attributeType == UnsAttributeType.Data)\r\n dataGroup = msg.packet.message.data.dataGroup ?? \"\";\r\n if (attributeType == UnsAttributeType.Table)\r\n dataGroup = msg.packet.message.table.dataGroup ?? \"\";\r\n if (attributeType == UnsAttributeType.Event)\r\n dataGroup = msg.packet.message.event.dataGroup ?? \"\";\r\n\r\n this.registerUniqueTopic({\r\n timestamp: time,\r\n topic: msg.topic,\r\n attribute: msg.attribute,\r\n attributeType: attributeType,\r\n description: msg.description,\r\n tags: msg.tags,\r\n attributeNeedsPersistence: msg.attributeNeedsPersistence,\r\n dataGroup\r\n });\r\n\r\n const fullTopic = `${msg.topic}${msg.attribute}`;\r\n const sequenceId = this.currentSequenceId.get(msg.topic) ?? 0;\r\n this.currentSequenceId.set(msg.topic, sequenceId + 1);\r\n msg.packet.sequenceId = sequenceId;\r\n\r\n if (msg.packet.message.data) {\r\n const newValue = msg.packet.message.data.value;\r\n const newUom: MeasurementUnit = msg.packet.message.data.uom;\r\n const lastValueEntry = this.lastValues.get(fullTopic);\r\n const currentTime = new Date(msg.packet.message.data.time);\r\n\r\n if (lastValueEntry) {\r\n const intervalBetweenMessages = currentTime.getTime() - lastValueEntry.timestamp.getTime();\r\n const lastValue = lastValueEntry.value;\r\n this.lastValues.set(fullTopic, { value: newValue, uom: newUom, timestamp: currentTime });\r\n // Compute the delta and manage cumulative resets\r\n if (valueIsCumulative == true && typeof newValue === \"number\" && typeof lastValue === \"number\") {\r\n // Skip if newValue is 0 (likely a glitch)\r\n if (newValue === 0) {\r\n return; // Don't process or enqueue\r\n }\r\n const delta = newValue - lastValue;\r\n msg.packet.message.data.value = delta < 0 ? newValue : delta;\r\n }\r\n msg.packet.interval = intervalBetweenMessages;\r\n await this.enqueueMessageToWorkerQueue(fullTopic, JSON.stringify(msg.packet));\r\n } else {\r\n this.lastValues.set(fullTopic, { value: newValue, uom: newUom, timestamp: currentTime });\r\n logger.debug(`${this.instanceNameWithSuffix} - Need one more packet to calculate interval on topic ${fullTopic}`);\r\n if (valueIsCumulative === false) {\r\n await this.enqueueMessageToWorkerQueue(fullTopic, JSON.stringify(msg.packet));\r\n } else {\r\n logger.debug(`${this.instanceNameWithSuffix} - Need one more packet to calculate difference on value in data for topic ${fullTopic}`);\r\n }\r\n }\r\n } else if (msg.packet.message.command) {\r\n await this.enqueueMessageToWorkerQueue(fullTopic, JSON.stringify(msg.packet));\r\n } else if (msg.packet.message.event) {\r\n await this.enqueueMessageToWorkerQueue(fullTopic, JSON.stringify(msg.packet));\r\n } else if (msg.packet.message.table) {\r\n await this.enqueueMessageToWorkerQueue(fullTopic, JSON.stringify(msg.packet));\r\n }\r\n } catch (error: any) {\r\n logger.error(`${this.instanceNameWithSuffix} - Error publishing message to topic ${msg.topic}${msg.attribute}: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * Stops the UnsProxy instance and cleans up resources.\r\n */\r\n public async stop(): Promise<void> {\r\n super.stop();\r\n // Terminate the worker thread if it exists.\r\n if (this.worker) {\r\n try {\r\n const exitCode = await this.worker.terminate();\r\n logger.info(`${this.instanceNameWithSuffix} - Worker terminated with exit code ${exitCode}`);\r\n } catch (error: any) {\r\n logger.error(`${this.instanceNameWithSuffix} - Error terminating worker: ${error.message}`);\r\n }\r\n }\r\n \r\n // Optionally, handle any pending enqueues.\r\n for (const [id, pending] of this.pendingEnqueues) {\r\n pending.reject(new Error(\"UnsProxy has been stopped\"));\r\n this.pendingEnqueues.delete(id);\r\n }\r\n }\r\n\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"uns-mqtt-proxy.js","sourceRoot":"","sources":["../../src/uns-mqtt/uns-mqtt-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync } from \"fs\";\nimport { IClientPublishOptions } from \"mqtt\";\nimport * as path from \"path\";\nimport { Worker } from \"worker_threads\";\nimport { fileURLToPath } from \"url\";\nimport { basePath } from \"../base-path.js\";\nimport logger from \"../logger.js\";\nimport { IMqttMessage, IUnsPacket, IUnsParameters, UnsEvents, ValueType } from \"../uns/uns-interfaces.js\";\nimport { MeasurementUnit } from \"../uns/uns-measurements.js\";\nimport { UnsPacket } from \"../uns/uns-packet.js\";\nimport { IMqttParameters, IMqttWorkerData } from \"./mqtt-interfaces.js\";\nimport { MqttTopicBuilder } from \"./mqtt-topic-builder.js\";\nimport UnsProxy from \"../uns/uns-proxy.js\";\nimport { UnsAttributeType } from \"../graphql/schema.js\";\n\nconst packageJsonPath = path.join(basePath, \"package.json\");\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf8\"));\n\nconst moduleDirectory = path.dirname(fileURLToPath(import.meta.url));\nconst packageRoot = path.resolve(moduleDirectory, \"..\", \"..\");\nconst workerScriptPath = path.join(packageRoot, \"dist/uns-mqtt/mqtt-worker-init.js\");\n\nexport enum MessageMode {\n Raw = 'raw', // Send only the original message\n Delta = 'delta', // Send only the delta message\n Both = 'both' // Send both the original and delta messages\n}\n\nexport default class UnsMqttProxy extends UnsProxy {\n private lastValues: Map<string, { value: ValueType; uom: string; timestamp: Date }> = new Map();\n private worker: Worker;\n private pendingEnqueues: Map<string, { resolve: () => void; reject: (reason?: any) => void }> = new Map();\n private unsParameters: IUnsParameters;\n protected processStatusTopic: string;\n public instanceName: string;\n private currentSequenceId: Map<string, number> = new Map();\n private topicBuilder: MqttTopicBuilder;\n\n constructor(\n mqttHost: string,\n processName: string,\n instanceName: string,\n unsParameters?: IUnsParameters,\n publisherActive: boolean = false,\n subscriberActive: boolean = false\n ) {\n super();\n this.instanceName = instanceName;\n // Create the topic builder using packageJson values and the processName.\n this.topicBuilder = new MqttTopicBuilder(`uns-infra/${MqttTopicBuilder.sanitizeTopicPart(packageJson.name)}/${MqttTopicBuilder.sanitizeTopicPart(packageJson.version)}/${MqttTopicBuilder.sanitizeTopicPart(processName)}/`);\n\n // Generate the processStatusTopic using the builder.\n this.processStatusTopic = this.topicBuilder.getProcessStatusTopic();\n // Derive the instanceStatusTopic by appending the instance name.\n this.instanceStatusTopic = this.processStatusTopic + instanceName + \"/\";\n\n // Concatenate processName with instanceName for the worker identification.\n this.instanceNameWithSuffix = `${processName}-${instanceName}`;\n \n const mqttParameters: IMqttParameters = {\n mqttSubToTopics: unsParameters?.mqttSubToTopics ?? [],\n username: unsParameters?.username ?? \"\",\n password: unsParameters?.password ?? \"\",\n mqttSSL: unsParameters?.mqttSSL ?? false,\n statusTopic: this.instanceStatusTopic,\n };\n this.unsParameters = unsParameters ?? {};\n this.startQueueWorker(mqttHost, this.instanceNameWithSuffix, mqttParameters, publisherActive, subscriberActive);\n }\n\n /**\n * Starts a worker thread to process the throttled publish queue.\n */\n private startQueueWorker(\n mqttHost: string,\n instanceNameWithSuffix: string,\n mqttParameters: IMqttParameters,\n publisherActive: boolean,\n subscriberActive: boolean\n ): void {\n const workerData: IMqttWorkerData = {\n publishThrottlingDelay: this.unsParameters.publishThrottlingDelay ?? 1,\n subscribeThrottlingDelay: this.unsParameters.subscribeThrottlingDelay ?? 1,\n persistToDisk: false,\n mqttHost: mqttHost,\n instanceNameWithSuffix: instanceNameWithSuffix,\n mqttParameters: mqttParameters,\n publisherActive,\n subscriberActive\n };\n\n this.worker = new Worker(workerScriptPath, { workerData });\n\n this.worker.on(\"message\", (msg) => {\n if (msg && msg.command === \"enqueueResult\" && msg.id) {\n const pending = this.pendingEnqueues.get(msg.id);\n if (pending) {\n if (msg.status === \"success\" && msg.topic && msg.message) {\n pending.resolve();\n } else {\n pending.reject(new Error(msg.error));\n }\n this.pendingEnqueues.delete(msg.id);\n }\n } else if (msg && msg.command === \"input\") {\n this.event.emit(\"input\", { topic: msg.topic, message: msg.message.toString(), packet: msg.packet });\n } else if (msg && (msg.command === \"handover_subscriber\" || msg.command === \"handover_publisher\")) {\n this.event.emit(\"mqttWorker\", { command: msg.command, batchSize: msg.batchSize, referenceHash: msg.referenceHash, instanceName: this.instanceName });\n } else if (msg && msg.command === \"mqttProxyStatus\") {\n this.event.emit(\"mqttProxyStatus\", { event: msg.event, value: msg.value, uom: msg.uom, statusTopic: msg.statusTopic });\n }\n });\n\n this.worker.on(\"error\", (err) => {\n logger.error(\"Error in worker:\", err);\n });\n\n this.worker.on(\"exit\", (code) => {\n if (code !== 0) {\n logger.error(`Worker exited with code ${code}`);\n }\n });\n }\n\n /**\n * Enqueues a message to the worker queue.\n *\n * @param topic - The topic to which the message belongs.\n * @param message - The message to be enqueued.\n * @param options - Optional publish options.\n * @returns A promise that resolves when the message is successfully enqueued.\n */\n private async enqueueMessageToWorkerQueue(topic: string, message: string, options?: IClientPublishOptions): Promise<void> {\n return new Promise((resolve, reject) => {\n // const id: string = String(this.currentSequenceId.get(topic) ?? 0);\n const id = `${Date.now()}-${Math.random()}`;\n this.pendingEnqueues.set(id, { resolve, reject });\n this.worker.postMessage({ command: \"enqueue\", id, topic, message, options });\n });\n }\n\n /**\n * Sets the publisher active state.\n *\n * @param batchSize - Optional batch size.\n * @param referenceHash - Optional reference hash.\n */\n public setPublisherActive(batchSize?: number, referenceHash?: string): void {\n this.worker.postMessage({ command: \"setPublisherActive\", batchSize, referenceHash });\n }\n\n /**\n * Sets the publisher to passive mode.\n * @returns A promise that resolves when the publisher is set to passive.\n */\n public setPublisherPassive(): Promise<UnsEvents[\"mqttWorker\"]> {\n this.worker.postMessage({ command: \"setPublisherPassive\"});\n return new Promise((resolve) => {\n this.event.on(\"mqttWorker\", (msg: UnsEvents[\"mqttWorker\"]) => {\n if (msg.command === \"handover_publisher\") {\n logger.info(`${this.instanceNameWithSuffix} - Publisher set to passive.`);\n resolve(msg);\n }\n });\n });\n }\n\n /**\n * Sets the subscriber active state.\n *\n * @param batchSize - Optional batch size.\n * @param referenceHash - Optional reference hash.\n */\n public setSubscriberActive(batchSize?: number, referenceHash?: string): void {\n this.worker.postMessage({ command: \"setSubscriberActive\", batchSize, referenceHash });\n }\n\n /**\n * Sets the subscriber to passive mode.\n * @returns A promise that resolves when the subscriber is set to passive.\n */\n public setSubscriberPassive(): Promise<UnsEvents[\"mqttWorker\"]> {\n this.worker.postMessage({ command: \"setSubscriberPassive\"});\n return new Promise((resolve) => {\n this.event.on(\"mqttWorker\", (msg: UnsEvents[\"mqttWorker\"]) => {\n if (msg.command === \"handover_subscriber\") {\n logger.info(`${this.instanceNameWithSuffix} - Publisher set to passive.`);\n resolve(msg);\n }\n });\n });\n }\n\n\n /**\n * Sets the subscriber to passive mode and allows the publisher to run\n * until the queue is empty (all messages are processed).\n */\n public async setSubscriberPassiveAndDrainQueue(): Promise<UnsEvents[\"mqttWorker\"]> {\n return new Promise(async (resolve) => {\n const mqttWorkerData = await this.setSubscriberPassive();\n while (this.pendingEnqueues.size > 0) {\n await new Promise((resolve) => setTimeout(resolve, 100)); // Poll every 100ms\n }\n logger.info(`${this.instanceNameWithSuffix} - Subscriber set to passive and queue drained.`);\n resolve(mqttWorkerData);\n });\n }\n\n /**\n * Processes and publishes MQTT messages based on the selected message mode.\n *\n * @param mqttMessage - The MQTT message object.\n * @param mode - The message mode (Raw, Delta, or Both).\n */\n public publishMqttMessage(mqttMessage: IMqttMessage | null, mode: MessageMode = MessageMode.Raw) {\n if (mqttMessage) {\n if (mqttMessage.packet) {\n const time = UnsPacket.formatToISO8601(new Date());\n switch (mode) {\n case MessageMode.Raw: {\n this.processAndEnqueueMessage(mqttMessage, time, false);\n break;\n }\n case MessageMode.Delta: {\n const deltaMessage = { ...mqttMessage };\n deltaMessage.attribute = `${mqttMessage.attribute}-delta`;\n deltaMessage.description = `${mqttMessage.description} (delta)`;\n this.processAndEnqueueMessage(deltaMessage, time, true);\n break;\n }\n case MessageMode.Both: {\n this.processAndEnqueueMessage(mqttMessage, time, false);\n const deltaMessageBoth = { ...mqttMessage };\n deltaMessageBoth.attribute = `${mqttMessage.attribute}-delta`;\n deltaMessageBoth.description = `${mqttMessage.description} (delta)`;\n this.processAndEnqueueMessage(deltaMessageBoth, time, true);\n break;\n }\n } \n } else {\n logger.error(`${this.instanceNameWithSuffix} - Error publishing mqtt message: mqttMessage.packet must be defined.`);\n }\n } else {\n logger.error(`${this.instanceNameWithSuffix} - Error publishing mqtt message: mqttMessage must be defined.`);\n }\n }\n\n /**\n * Publishes a message to a specified topic.\n *\n * @param topic - The MQTT topic.\n * @param message - The message to publish.\n * @returns A promise that resolves when enqueued.\n */\n public publishMessage(topic: string, message: string): Promise<void> {\n return this.enqueueMessageToWorkerQueue(topic, message);\n }\n\n /**\n * Parses an MQTT packet from a JSON string.\n *\n * @param mqttPacket - The MQTT packet string.\n * @returns A parsed IUnsPacket object or null.\n */\n public parseMqttPacket(mqttPacket: string): IUnsPacket | null {\n return UnsPacket.parseMqttPacket(mqttPacket, this.instanceNameWithSuffix);\n }\n\n /**\n * Subscribes asynchronously to one or more topics.\n *\n * @param topics - A topic or list of topics.\n */\n public subscribeAsync(topics: string | string[]): void {\n this.worker.postMessage({ command: \"subscribeAsync\", topics });\n }\n\n /**\n * Unsubscribes asynchronously from the given topics.\n *\n * @param topics - A list of topics.\n */\n public unsubscribeAsync(topics: string[]): void {\n this.worker.postMessage({ command: \"unsubscribeAsync\", topics });\n }\n\n /**\n * Processes and enqueues a message to the worker queue, including handling\n * sequencing, value differences, and tracking of unique topics.\n *\n * @param msg - The MQTT message to process.\n * @param time - The timestamp.\n * @param valueIsCumulative - Whether the value is cumulative.\n */\n private async processAndEnqueueMessage(msg: IMqttMessage, time: string, valueIsCumulative: boolean = false): Promise<void> {\n try {\n const attributeType =\n msg.packet.message.data ? UnsAttributeType.Data :\n msg.packet.message.event ? UnsAttributeType.Event :\n msg.packet.message.table ? UnsAttributeType.Table : null;\n \n let dataGroup = \"\";\n if (attributeType == UnsAttributeType.Data)\n dataGroup = msg.packet.message.data.dataGroup ?? \"\";\n if (attributeType == UnsAttributeType.Table)\n dataGroup = msg.packet.message.table.dataGroup ?? \"\";\n if (attributeType == UnsAttributeType.Event)\n dataGroup = msg.packet.message.event.dataGroup ?? \"\";\n\n this.registerUniqueTopic({\n timestamp: time,\n topic: msg.topic,\n attribute: msg.attribute,\n attributeType: attributeType,\n description: msg.description,\n tags: msg.tags,\n attributeNeedsPersistence: msg.attributeNeedsPersistence,\n dataGroup\n });\n\n const fullTopic = `${msg.topic}${msg.attribute}`;\n const sequenceId = this.currentSequenceId.get(msg.topic) ?? 0;\n this.currentSequenceId.set(msg.topic, sequenceId + 1);\n msg.packet.sequenceId = sequenceId;\n\n if (msg.packet.message.data) {\n const newValue = msg.packet.message.data.value;\n const newUom: MeasurementUnit = msg.packet.message.data.uom;\n const lastValueEntry = this.lastValues.get(fullTopic);\n const currentTime = new Date(msg.packet.message.data.time);\n\n if (lastValueEntry) {\n const intervalBetweenMessages = currentTime.getTime() - lastValueEntry.timestamp.getTime();\n const lastValue = lastValueEntry.value;\n this.lastValues.set(fullTopic, { value: newValue, uom: newUom, timestamp: currentTime });\n // Compute the delta and manage cumulative resets\n if (valueIsCumulative == true && typeof newValue === \"number\" && typeof lastValue === \"number\") {\n // Skip if newValue is 0 (likely a glitch)\n if (newValue === 0) {\n return; // Don't process or enqueue\n }\n const delta = newValue - lastValue;\n msg.packet.message.data.value = delta < 0 ? newValue : delta;\n }\n msg.packet.interval = intervalBetweenMessages;\n await this.enqueueMessageToWorkerQueue(fullTopic, JSON.stringify(msg.packet));\n } else {\n this.lastValues.set(fullTopic, { value: newValue, uom: newUom, timestamp: currentTime });\n logger.debug(`${this.instanceNameWithSuffix} - Need one more packet to calculate interval on topic ${fullTopic}`);\n if (valueIsCumulative === false) {\n await this.enqueueMessageToWorkerQueue(fullTopic, JSON.stringify(msg.packet));\n } else {\n logger.debug(`${this.instanceNameWithSuffix} - Need one more packet to calculate difference on value in data for topic ${fullTopic}`);\n }\n }\n } else if (msg.packet.message.command) {\n await this.enqueueMessageToWorkerQueue(fullTopic, JSON.stringify(msg.packet));\n } else if (msg.packet.message.event) {\n await this.enqueueMessageToWorkerQueue(fullTopic, JSON.stringify(msg.packet));\n } else if (msg.packet.message.table) {\n await this.enqueueMessageToWorkerQueue(fullTopic, JSON.stringify(msg.packet));\n }\n } catch (error: any) {\n logger.error(`${this.instanceNameWithSuffix} - Error publishing message to topic ${msg.topic}${msg.attribute}: ${error.message}`);\n }\n }\n\n /**\n * Stops the UnsProxy instance and cleans up resources.\n */\n public async stop(): Promise<void> {\n super.stop();\n // Terminate the worker thread if it exists.\n if (this.worker) {\n try {\n const exitCode = await this.worker.terminate();\n logger.info(`${this.instanceNameWithSuffix} - Worker terminated with exit code ${exitCode}`);\n } catch (error: any) {\n logger.error(`${this.instanceNameWithSuffix} - Error terminating worker: ${error.message}`);\n }\n }\n \n // Optionally, handle any pending enqueues.\n for (const [id, pending] of this.pendingEnqueues) {\n pending.reject(new Error(\"UnsProxy has been stopped\"));\n this.pendingEnqueues.delete(id);\n }\n }\n\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ws-proxy.js","sourceRoot":"","sources":["../../src/uns-mqtt/ws-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import WebSocket from 'ws';\
|
|
1
|
+
{"version":3,"file":"ws-proxy.js","sourceRoot":"","sources":["../../src/uns-mqtt/ws-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import WebSocket from 'ws';\nimport logger from '../logger.js';\n\nexport interface WsEvents {\n deal: { message: string};\n input: { message: string };\n error: { code: number; message: string };\n reconnect: {}; // Add reconnect event with an empty payload or specific data as needed\n}\n\nexport interface IWsParameters {\n username?: string;\n statusPath?: string;\n}\n\nclass WsEventEmitter<Events extends Record<string, any>> {\n private listeners: { [K in keyof Events]?: Array<(event: Events[K]) => void> } = {};\n\n on<K extends keyof Events>(eventName: K, listener: (event: Events[K]) => void): void {\n if (!this.listeners[eventName]) this.listeners[eventName] = [];\n this.listeners[eventName]!.push(listener);\n }\n\n off<K extends keyof Events>(eventName: K, listener: (event: Events[K]) => void): void {\n if (!this.listeners[eventName]) return;\n this.listeners[eventName] = this.listeners[eventName]!.filter((l) => l !== listener);\n }\n\n emit<K extends keyof Events>(eventName: K, event: Events[K]): void {\n if (!this.listeners[eventName]) return;\n this.listeners[eventName]!.forEach((listener) => listener(event));\n }\n}\n\nexport default class WsProxy {\n // Other properties and methods...\n public event: WsEventEmitter<WsEvents> = new WsEventEmitter<WsEvents>();\n protected wsClient: WebSocket;\n private wsUrl: string;\n private instanceName: string;\n private reconnectDelay = 3000;\n private maxReconnectAttempts = 5;\n private reconnectAttempts = 0;\n\n constructor(wsUrl: string, instanceName: string) {\n this.wsUrl = wsUrl;\n this.instanceName = instanceName;\n }\n\n private reconnect() {\n if (this.reconnectAttempts < this.maxReconnectAttempts) {\n setTimeout(() => {\n logger.info(`${this.instanceName} - Attempting to reconnect... (${this.reconnectAttempts + 1})`);\n this.reconnectAttempts++;\n this.start().then(() => {\n logger.info(`${this.instanceName} - Reconnected successfully`);\n this.event.emit('reconnect', {}); // Emit reconnect event here\n }).catch(() => logger.error(`${this.instanceName} - Reconnect attempt failed`));\n }, this.reconnectDelay);\n } else {\n logger.error(`${this.instanceName} - Maximum reconnect attempts reached. Giving up.`);\n }\n }\n\n // Starts the WebSocket connection\n public start(): Promise<void> {\n logger.info(`${this.instanceName} - Connecting to WebSocket server...`);\n\n return new Promise((resolve, reject) => {\n this.wsClient = new WebSocket(this.wsUrl);\n\n this.wsClient.on('open', () => {\n logger.info(`${this.instanceName} - Connected to WebSocket server at ${this.wsUrl}`);\n this.reconnectAttempts = 0; // Reset the reconnect attempts after a successful connection\n resolve();\n });\n\n this.wsClient.on('message', (data: WebSocket.Data) => {\n const message = typeof data === 'string' ? data : data.toString();\n// logger.info(`${this.instanceName} - Message received from server: ${message}`);\n this.event.emit('input', { message });\n });\n\n this.wsClient.on('error', (error) => {\n logger.error(`${this.instanceName} - WebSocket client error: ${(error as Error).message}`);\n this.event.emit('error', { code: 0, message: (error as Error).message });\n reject(error);\n });\n\n this.wsClient.on('close', (code, reason) => {\n logger.info(`${this.instanceName} - WebSocket connection closed: ${code} - ${reason}`);\n // Attempt reconnection for non-normal closure (code 1000 is normal)\n if (code !== 1000) {\n this.reconnect();\n }\n });\n });\n }\n\n // Stops the WebSocket connection\n public stop() {\n logger.info(`${this.instanceName} - Disconnecting from WebSocket server...`);\n if (this.wsClient) {\n this.wsClient.close(1000, 'Client closed connection');\n logger.info(`${this.instanceName} - Disconnected from WebSocket server.`);\n }\n }\n}\n"]}
|