Skip to content

KL-300: Upgrade aedes to v0.51.3 with OTel instrumentation compatibility#1

Open
rajathongal-intangles wants to merge 31 commits intomainfrom
KL-300-upgrade-mqt-ts-and-check-otel-instrumentation-compatibility
Open

KL-300: Upgrade aedes to v0.51.3 with OTel instrumentation compatibility#1
rajathongal-intangles wants to merge 31 commits intomainfrom
KL-300-upgrade-mqt-ts-and-check-otel-instrumentation-compatibility

Conversation

@rajathongal-intangles
Copy link
Copy Markdown
Collaborator

@rajathongal-intangles rajathongal-intangles commented Mar 11, 2026

Summary

Merges upstream aedes v0.51.3 (last CJS release before ESM migration in v1.0.0) and applies structural changes required by aedes-otel-instrumentation for OpenTelemetry auto-span creation.

Upstream merge (v0.50.0 → v0.51.3)

Bug fixes and improvements from upstream:

  • v0.50.1: TypeScript module export fix for ES6 compliance
  • v0.51.0: Add opts.keepaliveLimit option, fix closeSameClients for already-closed clients
  • v0.51.1: Remove erroneous console.error
  • v0.51.2: Fix — delete will from persistence on clean disconnect
  • v0.51.3: Fix memory leak in connected clients counter

Dependency updates

Package Before After
mqemitter ^5.0.0 ^6.0.0
mqtt-packet ^8.2.0 ^9.0.0
retimer ^3.0.0 ^4.0.0
hyperid ^3.1.1 ^3.2.0
uuid - ^10.0.0

Note: Consumers using mqemitter-redis must bump to ~6.1.0 to match mqemitter@^6.0.0.

OTel instrumentation compatibility changes

aedes-otel-instrumentation (v0.2.0) uses @opentelemetry/instrumentation's InstrumentationNodeModuleFile to monkey-patch aedes handler functions. The published npm package includes a postinstall: "patch-package" script but does NOT ship the patch files (patches/ is not in the files array). This means the patches are never applied, and the instrumentation silently fails to create spans.

We apply the equivalent changes directly in the fork so the instrumentation works out of the box.

1. Named exports (all handler + write files)

Changed from default exports to named exports so shimmer.wrap(moduleExports, 'handleConnect', ...) can locate the function:

- module.exports = handleConnect
+ module.exports = { handleConnect }

Files changed: connect.js, publish.js, subscribe.js, ping.js, puback.js, pubrec.js, pubrel.js, unsubscribe.js, handlers/index.js, write.js

All require() call sites updated to use destructuring (const { handleConnect } = require(...)).

2. Prototype methods for handler functions

Moved handle, preConnect, authenticate, authorizePublish, authorizeSubscribe from instance closures/properties to Aedes.prototype methods so aedes-otel-instrumentation can monkey-patch them:

  // Constructor
- this.preConnect = opts.preConnect
- this.authenticate = opts.authenticate
- this.authorizePublish = opts.authorizePublish
- this.authorizeSubscribe = opts.authorizeSubscribe
+ this._preConnect = opts.preConnect
+ this._authenticate = opts.authenticate
+ this._authorizePublish = opts.authorizePublish
+ this._authorizeSubscribe = opts.authorizeSubscribe

  // Prototype
+ Aedes.prototype.preConnect = function (client, packet, cb) {
+   this._preConnect(client, packet, cb)
+ }
+ Aedes.prototype.authenticate = function (client, user, pass, cb) {
+   this._authenticate(client, user, pass, cb)
+ }

3. wrapDeliveryFunc hook

New wrapDeliveryFunc option and prototype method — called in subscribe.js's addSubs() before registering the delivery function. Allows aedes-otel-instrumentation to wrap each subscription's delivery callback to create {topic} receive spans.

Breaking changes for consumers

aedes.handle must be bound when used as a callback

Since handle moved from a closure (capturing that) to a prototype method (using this), passing it as a callback requires .bind(aedes):

- server = require("net").createServer(aedes.handle);
+ server = require("net").createServer(aedes.handle.bind(aedes));

Direct property assignment still works

Overriding handlers at the instance level (e.g. aedes.authenticate = customFn) still works — instance properties shadow prototype methods.

What this enables

With these changes, aedes-otel-instrumentation can now auto-create:

  • mqtt.connect spans (from handleConnect patch)
  • {topic} publish spans (from handlePublish patch)
  • {topic} receive spans (from wrapDeliveryFunc + handleSubscribe patch)
  • Connection attribute propagation (from Aedes.prototype.handle patch)
  • mqtt.server.duration and mqtt.client.duration metrics

Intangles customizations preserved

  • emitPacket in aedes.js — IMEI regex filter + SUPPRESS_MQTT_EVENTS flag — unchanged
  • aedes.d.ts CommonJS export declaration — unchanged

Why not v1.0.0?

Upstream v1.0.0+ migrated to ESM ("type": "module"), which is incompatible with the Backend's CommonJS require('aedes'). v0.51.3 is the last CJS release.

Related PRs

  • intangles: Intangles/intangles#8495

peeveen and others added 30 commits July 24, 2023 14:12
Co-authored-by: steven.frew <steven.frew@corporatemodelling.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
BREAKING CHANGE: Min node version >= 16
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3 to 4.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](actions/setup-node@v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [mqtt-packet](https://github.com/mqttjs/mqtt-packet) from 8.2.1 to 9.0.0.
- [Release notes](https://github.com/mqttjs/mqtt-packet/releases)
- [Commits](mqttjs/mqtt-packet@v8.2.1...v9.0.0)

---
updated-dependencies:
- dependency-name: mqtt-packet
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Daniel Lando <daniel.sorridi@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Daniel Lando <daniel.sorridi@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Uladzimir Danko <uladzimirdanko@uladzimirsmbp14.home>
Upgrade mqtt-packet ^8, mqemitter ^5, aedes-persistence ^9,
aedes-packet ^3, uuid ^9, hyperid ^3.1. Remove bulk-write-stream.
Node engine bumped to >=16. Enables aedes-otel-instrumentation
compatibility (requires mqtt-packet >=8).
Merge upstream aedes v0.51.3 (last CJS version) which includes:
- Memory leak fix in connected clients counter
- Will deletion on disconnect fix
- keepaliveLimit option
- closeSameClients fix

Add OTel instrumentation compatibility changes required by
aedes-otel-instrumentation:
- Convert all handler/write exports to named exports
- Move handler functions (preConnect, authenticate, authorizePublish,
  authorizeSubscribe, handle) from instance closures to prototype methods
- Add wrapDeliveryFunc hook for tracing message delivery spans
- Update all require() sites to use destructuring
@rajathongal-intangles rajathongal-intangles changed the title KL-300: Upgrade aedes dependencies to 0.50.0 for OTel instrumentation KL-300: Upgrade aedes to v0.51.3 with OTel instrumentation compatibility Mar 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants