Dmytro Shteflyuk created THRIFT-6149:
----------------------------------------
Summary: Ruby Binary and Compact protocols should avoid decoding
skipped strings
Key: THRIFT-6149
URL: https://issues.apache.org/jira/browse/THRIFT-6149
Project: Thrift
Issue Type: Bug
Components: Ruby - Library
Reporter: Dmytro Shteflyuk
Assignee: Dmytro Shteflyuk
h3. Problem
When generated Ruby code encounters an unknown field with Thrift type
{{STRING}}, {{BaseProtocol#skip}} reads it through {{read_string}}. For the
Binary and Compact protocols, this first consumes the value as binary data and
then constructs a UTF-8 string even though the value is immediately discarded.
Skipping should consume the wire value without performing representation work
that cannot affect the result. JSON must retain its string-reading behavior
because JSON strings and binary values have different wire representations.
h3. Client impact
Ruby clients and servers skip unknown fields when communicating across schema
versions. Messages containing unknown string fields therefore create an
unnecessary temporary string for every skipped value and spend additional time
applying string encoding semantics.
The overhead scales with the number of skipped values. A focused benchmark
using 100,000 128-byte strings observed one fewer allocation per skipped value
and lower skip time for Binary and Compact protocols when consuming the raw
bytes directly. The wire format and decoded values of known fields are
unaffected.
h3. Reproduction
>From {{lib/rb}}, run:
{code:bash}
bundle exec ruby -Ilib -Iext <<'RUBY'
require "thrift"
class TrackingBinaryProtocol < Thrift::BinaryProtocol
attr_reader :reads
def initialize(transport)
super
@reads = []
end
def read_string
@reads << :string
super
end
def read_binary
@reads << :binary
super
end
end
transport = Thrift::MemoryBufferTransport.new
protocol = TrackingBinaryProtocol.new(transport)
protocol.write_string("value")
protocol.skip(Thrift::Types::STRING)
puts protocol.reads.join(" -> ")
RUBY
{code}
Testing on master commit {{9b10484ca7687af6cc67567df9d457d0f031748e}} produces:
{code}
string -> binary
{code}
The skipped value enters the string-decoding path before its underlying binary
bytes are consumed.
h3. Expected behavior
Binary and Compact protocols should consume skipped {{STRING}} values through
their raw binary readers, avoiding unnecessary string conversion. JSON and
custom protocols should retain the existing {{read_string}} contract unless
they explicitly specialize skipped-string handling.
Header and decorated protocols should preserve the behavior of their selected
or wrapped protocol. Skipping must consume exactly the same wire bytes as
before and must not change handling of known fields.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)