RUBY-3898 Remove dead cursor-pinning block, fix cursor id for OP_MSG#3073
Merged
comandeo-mongo merged 2 commits intoJul 8, 2026
Merged
Conversation
Operation::Result#has_cursor_id? checked replies.last.respond_to?(:cursor_id), which is only true for the legacy Protocol::Reply. Every modern reply is a Protocol::Msg, so the predicate was always false. Two call sites depended on it: - The load-balanced cursor pin/unpin block in executable.rb never ran. LB cursors already retain their connection via explicit ownership (Cursor holds @connection since RUBY-3616), so the block was a redundant guard. Removed. - The OpenTelemetry db.mongodb.cursor_id attribute on find/aggregate spans was gated on the dead predicate and never recorded. Remove has_cursor_id?, make base Result#cursor_id read the cursor id from the OP_MSG `cursor` subdocument (returning 0 when absent, so it is safe to call on any command result), and gate the tracer on cursor_id.positive?. Find and aggregate spans now record the cursor id.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes cursor ID handling for OP_MSG command replies by making Operation::Result#cursor_id work across modern responses, removing an always-false predicate, and ensuring OpenTelemetry spans can record db.mongodb.cursor_id for find/aggregate results.
Changes:
- Remove the dead
Operation::Result#has_cursor_id?predicate and updatecursor_idto read from the OP_MSGcursor.idsubdocument (defaulting to 0). - Remove the non-functional load-balanced cursor pin/unpin block guarded by the dead predicate.
- Update OpenTelemetry command tracing and specs to gate cursor context on
cursor_id.positive?and stubcursor_idin doubles.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| lib/mongo/operation/shared/executable.rb | Removes unreachable LB cursor pin/unpin logic guarded by the removed predicate. |
| lib/mongo/operation/result.rb | Removes has_cursor_id?; makes cursor_id work for OP_MSG cursor.id replies with a safe default. |
| lib/mongo/tracing/open_telemetry/command_tracer.rb | Changes cursor context gating to rely on cursor_id.positive? to enable recording cursor IDs on command spans. |
| spec/mongo/operation/result_spec.rb | Replaces has_cursor_id? tests with OP_MSG cursor-id extraction cases. |
| spec/mongo/tracing/open_telemetry/command_tracer_spec.rb | Updates doubles to stub cursor_id (removes predicate stubbing) and keeps span attribute expectations. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
result.cursor_id can be a BSON::Int64 when replies are deserialized in :bson mode (deserialize_as_bson: true). BSON::Int64 does not implement positive? and is not a valid OpenTelemetry attribute type, so process_cursor_context would raise NoMethodError once the always-false has_cursor_id? guard was removed. Unwrap to a plain Integer before the positivity check and before setting the span attribute.
jamis
approved these changes
Jul 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Operation::Result#has_cursor_id?checkedreplies.last.respond_to?(:cursor_id), which is only true for the legacyProtocol::Reply. Every modern reply is aProtocol::Msg, so the predicate was always false. Two call sites depended on it:executable.rbnever executed. LB cursors already retain their connection via explicit ownership (Cursorholds@connectionsince RUBY-3616, released byCursor#check_in_connection), so the block was a redundant guard.db.mongodb.cursor_idattribute onfind/aggregatespans was gated on the dead predicate and therefore never recorded (the request-message path only covers getMore/killCursors).Changes
lib/mongo/operation/shared/executable.rb— removed the dead LB cursor pin/unpin block. Transaction pinning, snapshot handling, andprocess_resultare unchanged.lib/mongo/operation/result.rb— removedhas_cursor_id?; made basecursor_idread the id from the OP_MSGcursorsubdocument (returning 0 when absent), so it is safe to call on any command result.lib/mongo/tracing/open_telemetry/command_tracer.rb— gateprocess_cursor_contextoncursor_id.positive?. Find/aggregate spans now recorddb.mongodb.cursor_id.#has_cursor_id?coverage inresult_spec.rbwith OP_MSG#cursor_idcases; updated tracer spec doubles to stubcursor_idinstead of the removed predicate.Test plan
bundle exec rubocopon all changed files — no offensesbundle exec rspec spec/mongo/operation/result_spec.rb spec/mongo/tracing/open_telemetry/command_tracer_spec.rb— 142 examples, 0 failuresbundle exec rspec spec/mongo/cursor_spec.rb spec/integration/cursor_pinning_spec.rb— 46 examples, 0 failures, 5 pending (LB-only cases, skipped on local replica set)cursor_pinning_speccases run in the Evergreen load-balanced variant (connection-retention regression guard)RUBY-3898