1- Thrift Ruby Software Library
2- http://thrift.apache.org
1+ # Thrift Ruby Software Library
32
4- == LICENSE:
3+ ## License
54
65Licensed to the Apache Software Foundation (ASF) under one
76or more contributor license agreements. See the NOTICE file
@@ -20,24 +19,183 @@ KIND, either express or implied. See the License for the
2019specific language governing permissions and limitations
2120under the License.
2221
23- == DESCRIPTION:
22+ # Using Thrift with Ruby
2423
25- Thrift is a strongly-typed language-agnostic RPC system.
26- This library is the ruby implementation for both clients and servers.
24+ Ruby bindings for the Apache Thrift RPC system. The gem contains the runtime
25+ types, transports, protocols, and servers used by generated Ruby code for both
26+ clients and services.
2727
28- == INSTALL:
28+ ## Compatibility
2929
30- $ gem install thrift
30+ - Ruby MRI >= 2.7 (tested against current supported releases).
31+ - JRuby works with the pure-Ruby implementation; the native extension is
32+ skipped automatically.
33+ - For the repo-wide transport, protocol, and server support matrix, see
34+ [ Language Feature Matrix] ( https://github.com/apache/thrift/blob/master/LANGUAGES.md ) . This README focuses on Ruby-specific
35+ behavior and migration notes.
3136
32- == CAVEATS:
37+ ## Installation
3338
34- This library provides the client and server implementations of thrift.
35- It does <em >not</em > provide the compiler for the .thrift files. To compile
36- .thrift files into language-specific implementations, please download the full
37- thrift software package.
39+ - Requirements: Ruby >= 2.7.
40+ - From RubyGems: ` gem install thrift `
41+ - From source: ` bundle install ` , ` gem build thrift.gemspec ` , then install the
42+ resulting ` thrift-*.gem ` . The native accelerator is built when the gem is
43+ installed on supported runtimes.
3844
39- == USAGE:
45+ ## Generating Ruby Code
4046
41- This section should get written by someone with the time and inclination.
42- In the meantime, look at existing code, such as the benchmark or the tutorial
43- in the full thrift distribution.
47+ The Ruby library does not include the Thrift compiler. Use a compiler built
48+ from the root of this repository to generate Ruby bindings:
49+
50+ thrift --gen rb path/to/service.thrift
51+ # with namespaced modules
52+ thrift --gen rb:namespaced --recurse path/to/service.thrift
53+
54+ Generated files are typically written to ` gen-rb/ ` and can be required
55+ directly from your application.
56+
57+ ## Basic Client Usage
58+
59+ $:.push File.expand_path('gen-rb', __dir__)
60+ require 'thrift'
61+ require 'calculator'
62+
63+ socket = Thrift::Socket.new('localhost', 9090)
64+ transport = Thrift::BufferedTransport.new(socket)
65+ protocol = Thrift::BinaryProtocol.new(transport)
66+ client = Calculator::Client.new(protocol)
67+
68+ transport.open
69+ puts client.add(1, 1)
70+ transport.close
71+
72+ ## Basic Server Usage
73+
74+ $:.push File.expand_path('gen-rb', __dir__)
75+ require 'thrift'
76+ require 'calculator'
77+
78+ class CalculatorHandler
79+ def add(a, b)
80+ a + b
81+ end
82+ end
83+
84+ handler = CalculatorHandler.new
85+ processor = Calculator::Processor.new(handler)
86+ server_transport = Thrift::ServerSocket.new(9090)
87+ transport_factory = Thrift::BufferedTransportFactory.new
88+ protocol_factory = Thrift::BinaryProtocolFactory.new
89+
90+ server = Thrift::ThreadedServer.new(processor, server_transport,
91+ transport_factory, protocol_factory)
92+ server.serve
93+
94+ ## Development and Tests
95+
96+ - ` bundle exec rake spec ` runs the Ruby specs. It expects a built Thrift
97+ compiler at ` ../../compiler/cpp/thrift ` .
98+ - ` bundle exec rake test ` runs the cross-language test suite; it must be
99+ executed from a full Thrift checkout.
100+ - ` bundle exec rake build_ext ` (implicit in the tasks above) compiles the
101+ optional native extension that accelerates protocols and buffers.
102+
103+ ## More Ruby Code
104+
105+ - Tutorial client and server: ` tutorial/rb/RubyClient.rb ` and ` tutorial/rb/RubyServer.rb `
106+ - Runtime benchmarks: ` lib/rb/benchmark `
107+ - Protocol benchmark: ` test/rb/benchmarks/protocol_benchmark.rb `
108+ - Library specs: ` lib/rb/spec `
109+ - Fuzzing harnesses and notes: ` lib/rb/test/fuzz `
110+ - Cross-language and integration tests: ` test/rb `
111+
112+ ## Breaking Changes
113+
114+ ### 0.23.0
115+
116+ The documented source-build flow now effectively requires Ruby ` 2.7+ ` .
117+ The committed development bundle no longer resolves on Ruby ` 2.6 `
118+ (` json-2.18.1 requires ruby version >= 2.7 ` ), so building and testing this
119+ library from source should be treated as ` 2.7+ ` .
120+
121+ Generated structs and unions now consistently raise
122+ ` Thrift::ProtocolException::INVALID_DATA ` for invalid payloads such as unset
123+ required fields, invalid enum values, or invalid union state. If your
124+ application or tests matched older exception types or messages, update them.
125+
126+ Regenerated Ruby clients now validate replies more strictly. Mismatched reply
127+ message types, method names, or sequence IDs raise
128+ ` Thrift::ApplicationException::INVALID_MESSAGE_TYPE ` ,
129+ ` Thrift::ApplicationException::WRONG_METHOD_NAME ` , or
130+ ` Thrift::ApplicationException::BAD_SEQUENCE_ID ` . If you relied on older,
131+ looser reply handling in servers, proxies, or tests, regenerate and update
132+ those call paths together.
133+
134+ Generated Ruby clients have never been safe to share across concurrent
135+ threads. A client tracks pending sequence IDs on a single reply stream, so use
136+ one client/transport pair per thread or serialize access yourself.
137+
138+ Treat ` Thrift::ApplicationException::BAD_SEQUENCE_ID ` as a correctness bug
139+ that needs immediate attention. It means the client read a reply whose
140+ sequence ID did not match the next pending request, so the connection may
141+ already be out of sync and you may be reading a reply intended for a
142+ different call. The most common cause is sharing one client across threads,
143+ but a buggy proxy or server can also cause it.
144+
145+ ### 0.13.0
146+
147+ Ruby development and CI moved to Ruby ` 2.4+ ` , but the runtime still claimed
148+ support for older interpreters. Treat Ruby ` < 2.4 ` on the ` 0.13.x ` line as
149+ best-effort, not guaranteed.
150+
151+ - Historical note for very old releases: the Ruby runtime was rearranged to use
152+ more Ruby-like names, and generated files switched to underscored filenames.
153+ If you are upgrading very old code, regenerate your Ruby bindings and update
154+ any old ` T* ` constants or legacy require paths such as
155+ ` TBinaryProtocol ` -> ` Thrift::BinaryProtocol ` .
156+ - ` rb:namespaced ` changes the generated file layout. Flat output from
157+ ` thrift --gen rb ` and namespaced output from ` thrift --gen rb:namespaced `
158+ use different require paths, so switch them atomically with regenerated code.
159+
160+ # --gen rb
161+ require 'calculator'
162+
163+ # --gen rb:namespaced
164+ require 'my_namespace/calculator'
165+
166+ ## Migration Notes
167+
168+ - If you upgrade across the stricter reply-validation changes, regenerate all
169+ Ruby stubs and deploy them with the matching Ruby runtime. Do not mix old
170+ generated code, new generated code, and new runtime code on the same client
171+ path without testing that combination.
172+ - If you receive ` Thrift::ApplicationException::BAD_SEQUENCE_ID ` , treat the
173+ connection as out of sync. Close it, create a new client/transport pair, and
174+ investigate the root cause before retrying.
175+ - Do not share one generated Ruby client across concurrent threads. Use one
176+ client/transport pair per thread, or serialize access to a shared client.
177+ - If you switch between ` thrift --gen rb ` and ` thrift --gen rb:namespaced ` ,
178+ regenerate all Ruby output and update ` require ` paths in the same change.
179+
180+ ## Runtime Notes
181+
182+ - Loading the ` thrift_native ` extension changes which implementation you are
183+ running. It replaces
184+ ` Thrift::Struct ` , ` Thrift::Union ` , and ` Thrift::CompactProtocol ` methods
185+ with C implementations in place. ` Thrift::BinaryProtocol ` remains available
186+ in pure Ruby, and the C-backed binary protocol is opt-in through
187+ ` Thrift::BinaryProtocolAcceleratedFactory ` or
188+ ` Thrift::BinaryProtocolAccelerated ` when that class is available.
189+ - The native extension is optional. If it cannot be built or loaded, Thrift
190+ falls back to the pure-Ruby implementation. This mainly changes performance
191+ and implementation details.
192+ - JRuby skips the native extension automatically and uses the pure-Ruby path.
193+ - Do not share one client instance across concurrent threads. A client tracks
194+ request and reply state on a single transport stream.
195+ - ` Thrift::NonblockingServer ` expects framed input. Use
196+ ` Thrift::FramedTransport ` with it on the wire.
197+ - Client and server must agree on transport and protocol choices. If you
198+ switch to SSL, HTTP, header transport, compact protocol, or namespaced
199+ generated code, update both ends together.
200+ - HTTPS client transport verifies peers by default, and ` Thrift::SSLSocket `
201+ performs a hostname check against the host you pass in.
0 commit comments