Skip to content

THRIFT-6149: Avoid decoding skipped Ruby strings - #3713

Merged
kpumuk merged 1 commit into
apache:masterfrom
kpumuk:rb-skip-string-decoding
Aug 14, 2026
Merged

THRIFT-6149: Avoid decoding skipped Ruby strings#3713
kpumuk merged 1 commit into
apache:masterfrom
kpumuk:rb-skip-string-decoding

Conversation

@kpumuk

@kpumuk kpumuk commented Aug 14, 2026

Copy link
Copy Markdown
Member

Ruby clients and servers skip fields they do not recognize when communicating across schema versions. The shared Ruby protocol path currently handles skipped STRING values through read_string. Binary and Compact protocols therefore construct a UTF-8 string from the raw bytes even though the value is immediately discarded.

This change gives protocols control over how skipped strings are consumed. Binary and Compact use their binary readers, while the base protocol preserves the existing string behavior for custom protocols. JSON continues reading skipped values as strings because JSON strings and binary values have different wire representations. Header and decorated protocols forward the operation to their selected or wrapped protocol.

The wire bytes consumed are unchanged. The change only avoids unnecessary representation work when Binary or Compact string values are skipped.

Benchmarks

The benchmark used Ruby 4.0.6 on aarch64 Linux and skipped 100,000 strings of 128 bytes each. Each result is the median of five measured trials after one warm-up trial. The same temporary harness and configuration were run against master commit 9b10484ca7687af6cc67567df9d457d0f031748e and the proposed change:

bundle exec ruby /tmp/rb_skip_string_benchmark.rb
THRIFT_BENCHMARK_SKIP_NATIVE=1 bundle exec ruby /tmp/rb_skip_string_benchmark.rb
Mode and protocol Master median Proposed median Runtime delta Allocated objects
Native Binary 70.250 ms 56.999 ms -18.86% 303,181 → 203,181 (-32.98%)
Native Compact 59.493 ms 52.577 ms -11.63% 203,132 → 103,132 (-49.23%)
Native Binary accelerated 55.630 ms 44.984 ms -19.14% 203,180 → 103,180 (-49.22%)
Pure Ruby Binary 130.605 ms 120.119 ms -8.03% 306,355 → 206,355 (-32.64%)
Pure Ruby Compact 122.418 ms 108.034 ms -11.75% 306,258 → 206,258 (-32.65%)

JSON must retain its string-reading path. A separate alternating paired benchmark of 20,000 skipped JSON strings measured the forwarding overhead at +0.53% in native mode and +0.06% in pure Ruby, with unchanged allocations.

These are synthetic skip-only workloads on one Ruby version and architecture. The temporary harness is not included in the change.

  • Did you create an Apache Jira ticket? THRIFT-6149
  • If a ticket exists: Does your pull request title follow the pattern "THRIFT-NNNN: describe my issue"?
  • Did you squash your changes to a single commit? (not required, but preferred)
  • Did you do your best to avoid breaking changes? If one was needed, did you label the Jira ticket with "Breaking-Change"?
  • If your change does not involve any code, include [skip ci] anywhere in the commit message to free up build resources.

Client: rb

Co-Authored-By: OpenAI Codex (GPT-5.6) <codex@openai.com>
Copilot AI lite review requested due to automatic review settings August 14, 2026 12:39
@mergeable mergeable Bot added the ruby Pull requests that update Ruby code label Aug 14, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR optimizes Ruby’s protocol skip(Thrift::Types::STRING) path so Binary and Compact protocols can consume skipped STRING values without constructing/validating UTF-8 strings, while preserving the existing behavior for JSON and the base protocol.

Changes:

  • Introduces BaseProtocol#skip_string and routes BaseProtocol#skip(... STRING ...) through it.
  • Implements protocol-specific skip_string behavior (Binary/Compact via read_binary, JSON via read_string), and forwards through Header/Decorator protocols.
  • Adds Ruby specs validating the new delegation and skip behavior (including decorator/wrapper coverage).

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
lib/rb/lib/thrift/protocol/base_protocol.rb Adds skip_string hook and updates skip(STRING) to call it
lib/rb/lib/thrift/protocol/binary_protocol.rb Implements skip_string using read_binary to avoid UTF-8 conversion
lib/rb/lib/thrift/protocol/compact_protocol.rb Implements skip_string using read_binary to avoid UTF-8 conversion
lib/rb/lib/thrift/protocol/json_protocol.rb Implements skip_string via read_string to preserve JSON semantics
lib/rb/lib/thrift/protocol/header_protocol.rb Delegates skip_string to the selected underlying protocol
lib/rb/lib/thrift/protocol/protocol_decorator.rb Forwards skip_string to the decorated protocol
lib/rb/spec/binary_protocol_spec_shared.rb Tests that skipping STRING uses read_binary (not read_string)
lib/rb/spec/compact_protocol_spec.rb Tests that skipping STRING uses read_binary (not read_string)
lib/rb/spec/json_protocol_spec.rb Tests skipping unknown JSON string fields avoids base64 decoding and works through decorators
lib/rb/spec/header_protocol_spec.rb Tests HeaderProtocol delegates skip_string to its selected protocol
lib/rb/spec/protocol_decorator_spec.rb Tests ProtocolDecorator forwards skipped strings to the decorated protocol

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread lib/rb/lib/thrift/protocol/base_protocol.rb
@kpumuk
kpumuk merged commit e6d5738 into apache:master Aug 14, 2026
95 checks passed
@kpumuk
kpumuk deleted the rb-skip-string-decoding branch August 14, 2026 19:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ruby Pull requests that update Ruby code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants