Skip to content

fix preserve mysql2 stream queries and native tracing events#140

Merged
sohankshirsagar merged 3 commits intomainfrom
sohan/fix-mysql2-3.20.0
Mar 16, 2026
Merged

fix preserve mysql2 stream queries and native tracing events#140
sohankshirsagar merged 3 commits intomainfrom
sohan/fix-mysql2-3.20.0

Conversation

@sohankshirsagar
Copy link
Contributor

@sohankshirsagar sohankshirsagar commented Mar 16, 2026

Summary

Fix mysql2 compatibility issues introduced by the recent mysql2 v3.20.0 changes, especially the native TracingChannel work added in sidorares/node-mysql2#4178.

Our mysql2 instrumentation was relying on older callback-less query() behavior. After v3.20.0, stream-style queries could route through mysql2's new internal tracing path, which broke the /test/stream-query E2E flow and caused the request to hang before the query emitter delivered end. This change restores stable stream-query behavior by taking control of the callback-less query command construction path inside our instrumentation, while also re-emitting equivalent native mysql2:query tracing events so OTEL/APM subscribers still work.

This PR also fixes constructor wrapping for mysql2 connection classes by preserving new.target via Reflect.construct(...). That was needed because mysql2 v3.20.0 also changed class relationships around pool connections, and naïvely calling new OriginalConnection(...) from our wrapped constructor could break subclass instances like PoolConnection by returning the wrong prototype chain.

Changes

  • capture BaseConnection.createQuery when patching mysql2 so callback-less queries can be reconstructed without depending on wrapped constructors
  • bypass mysql2's internal callback-less query() implementation for emitter-style queries and enqueue the Query command directly via addCommand()
  • preserve stream-query recording by continuing to collect streamed rows and fields from result / fields / end
  • prefer the emitter lifecycle whenever mysql2 returns a callback-less object that is both thenable and EventEmitter-like
  • defer stream span finalization to avoid interfering with application listeners that send the HTTP response
  • re-emit equivalent native mysql2:query TracingChannel events around the bypassed path so native subscribers still observe streaming queries
  • switch wrapped connection construction to Reflect.construct(OriginalConnection, args, constructTarget) so wrapped constructors preserve new.target and return the correct subclass instance
  • fix PoolConnection/constructor compatibility so subclass-specific methods and prototype behavior remain intact after mysql2 class-wrapping changes
  • add an integration test that subscribes to node:diagnostics_channel and verifies native mysql2:query events are emitted for streaming queries

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

@tusk-dev
Copy link

tusk-dev bot commented Mar 16, 2026

Tusk is paused for this PR

View output

Tip

New to Tusk Unit Tests? Learn more here.

View check history

Commit Status Output Created (UTC)
f1257f7 Generated 35 tests - 35 passed Tests Mar 16, 2026 8:54PM
ebc2cbe Tusk is paused for this PR Output Mar 16, 2026 9:40PM

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 6 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/core/tracing/SpanUtils.ts">

<violation number="1" location="src/core/tracing/SpanUtils.ts:172">
P1: Don't throw when `stopRecordingChildSpans` is set in replay mode; this path is used to suppress nested instrumentation, and raising here will break replayed operations that intentionally run with child spans disabled.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@sohankshirsagar sohankshirsagar added the Tusk - Pause For Current PR Pause Tusk for future commits in the current PR label Mar 16, 2026
@sohankshirsagar sohankshirsagar merged commit abf6456 into main Mar 16, 2026
19 checks passed
@sohankshirsagar sohankshirsagar deleted the sohan/fix-mysql2-3.20.0 branch March 16, 2026 22:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Tusk - Pause For Current PR Pause Tusk for future commits in the current PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants