thrift_client 0.3.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG CHANGED
@@ -1,4 +1,12 @@
1
- v0.3.3 Allow for a timeout over all requests in a call.
1
+ v0.4.0. Add new EventMachine transport. This requires two layers of transport
2
+ configurability:
3
+ options[:transport] for EventMachine or Socket transports
4
+ options[:transport_wrapper] for optional Buffered or Framed Transport.
5
+ Clients will need to update their options to ensure they don't conflict with this change. (mperham)
6
+ Revert global timeouts. (ryanking)
7
+ Add support for HTTPClientTransport (Chris Sepic)
8
+
9
+ v0.3.3. Allow for a timeout over all requests in a call.
2
10
 
3
11
  v0.3.2. Fix connection close bug (nkallen, mattknox).
4
12
 
data/Manifest CHANGED
@@ -1,9 +1,21 @@
1
1
  CHANGELOG
2
2
  LICENSE
3
3
  Manifest
4
- README
4
+ README.rdoc
5
5
  Rakefile
6
6
  lib/thrift_client.rb
7
+ lib/thrift_client/connection.rb
8
+ lib/thrift_client/connection/base.rb
9
+ lib/thrift_client/connection/factory.rb
10
+ lib/thrift_client/connection/http.rb
11
+ lib/thrift_client/connection/socket.rb
12
+ lib/thrift_client/event_machine.rb
13
+ lib/thrift_client/simple.rb
7
14
  lib/thrift_client/thrift.rb
15
+ test/greeter/greeter.rb
16
+ test/greeter/greeter.thrift
17
+ test/greeter/server.rb
18
+ test/simple_test.rb
8
19
  test/test_helper.rb
20
+ test/thrift_client_http_test.rb
9
21
  test/thrift_client_test.rb
@@ -27,7 +27,7 @@ Instantiate a client:
27
27
  You can then make calls to the server via the <tt>client</tt> instance as if was your internal Thrift client. The connection will be opened lazily and methods will be proxied through.
28
28
 
29
29
  client.get_string_list_property("keyspaces")
30
-
30
+
31
31
  On failures, the client will try the remaining servers in the list before giving up. See ThriftClient for more.
32
32
 
33
33
  == Installation
@@ -36,6 +36,14 @@ You need Ruby 1.8 or 1.9. If you have those, just run:
36
36
 
37
37
  sudo gem install thrift_client
38
38
 
39
+ == Contributing
40
+
41
+ To contribute changes:
42
+
43
+ 1. Fork the project
44
+ 2. make your change, adding tests
45
+ 3. send a pull request to fauna and ryanking
46
+
39
47
  == Reporting problems
40
48
 
41
49
  The Github issue tracker is {here}[http://github.com/fauna/thrift_client/issues].
data/Rakefile CHANGED
@@ -14,4 +14,3 @@ Echoe.new("thrift_client") do |p|
14
14
  p.docs_host = "blog.evanweaver.com:~/www/bax/public/files/doc/"
15
15
  p.spec_pattern = "spec/*_spec.rb"
16
16
  end
17
-
@@ -0,0 +1,20 @@
1
+ module Connection
2
+ class Base
3
+ attr_accessor :transport, :server
4
+
5
+ def initialize(transport, transport_wrapper, server, timeout, error_hash)
6
+ @transport = transport
7
+ @transport_wrapper = transport_wrapper
8
+ @server = server
9
+ @timeout = timeout
10
+ @error_type = error_hash[:handles_error]
11
+ end
12
+
13
+ def connect!
14
+ raise NotImplementedError
15
+ end
16
+
17
+ def close
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,11 @@
1
+ module Connection
2
+ class Factory
3
+ def self.create(transport, transport_wrapper, server, timeout)
4
+ if transport == Thrift::HTTPClientTransport
5
+ Connection::HTTP.new(transport, transport_wrapper, server, timeout, :handles_error => Errno::ECONNREFUSED)
6
+ else
7
+ Connection::Socket.new(transport, transport_wrapper, server, timeout, :handles_error => Thrift::TransportException)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,18 @@
1
+ module Connection
2
+ class HTTP < Base
3
+ def connect!
4
+ uri = parse_server(@server)
5
+ @transport = Thrift::HTTPClientTransport.new(@server)
6
+ http = Net::HTTP.new(uri.host, uri.port)
7
+ http.use_ssl = uri.scheme == "https"
8
+ http.get(uri.path)
9
+ end
10
+
11
+ private
12
+ def parse_server(server)
13
+ uri = URI.parse(server)
14
+ raise ArgumentError, 'Servers must start with http' unless uri.scheme =~ /^http/
15
+ uri
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ module Connection
2
+ class Socket < Base
3
+ def close
4
+ @transport.close
5
+ end
6
+
7
+ def connect!
8
+ host, port = parse_server(@server)
9
+ @transport = @transport.new(*[host, port.to_i, @timeout])
10
+ @transport = @transport_wrapper.new(@transport) if @transport_wrapper
11
+ @transport.open
12
+ end
13
+
14
+ private
15
+
16
+ def parse_server(server)
17
+ host, port = server.to_s.split(":")
18
+ raise ArgumentError, 'Servers must be in the form "host:port"' unless host and port
19
+ [host, port]
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + "/connection")
2
+ require "base"
3
+ require "socket"
4
+ require "http"
5
+ require "factory"
@@ -0,0 +1,141 @@
1
+ raise RuntimeError, "The eventmachine transport requires Ruby 1.9.x" if RUBY_VERSION < '1.9.0'
2
+
3
+ require 'eventmachine'
4
+ require 'fiber'
5
+
6
+ # EventMachine-ready Thrift connection
7
+ # Should not be used with a transport wrapper since it already performs buffering in Ruby.
8
+ module Thrift
9
+ class EventMachineTransport < BaseTransport
10
+ def initialize(host, port=9090, timeout=5)
11
+ @host, @port, @timeout = host, port, timeout
12
+ @connection = nil
13
+ end
14
+
15
+ def open?
16
+ @connection && @connection.connected?
17
+ end
18
+
19
+ def open
20
+ @connection = EventMachineConnection.connect(@host, @port, @timeout)
21
+ end
22
+
23
+ def close
24
+ @connection.close
25
+ end
26
+
27
+ def read(sz)
28
+ @connection.blocking_read(sz)
29
+ end
30
+
31
+ def write(buf)
32
+ @connection.send_data(buf)
33
+ end
34
+ end
35
+
36
+ module EventMachineConnection
37
+ GARBAGE_BUFFER_SIZE = 4096 # 4kB
38
+
39
+ include EM::Deferrable
40
+
41
+ def self.connect(host='localhost', port=9090, timeout=5, &block)
42
+ EM.connect(host, port, self, host, port) do |conn|
43
+ conn.pending_connect_timeout = timeout
44
+ end
45
+ end
46
+
47
+ def trap
48
+ begin
49
+ yield
50
+ rescue Exception => ex
51
+ puts ex.message
52
+ puts ex.backtrace.join("\n")
53
+ end
54
+ end
55
+
56
+ def initialize(host, port=9090)
57
+ @host, @port = host, port
58
+ @index = 0
59
+ @reconnecting = false
60
+ @connected = false
61
+ @buf = ''
62
+ end
63
+
64
+ def close
65
+ trap do
66
+ @connected = false
67
+ close_connection(true)
68
+ end
69
+ end
70
+
71
+ def blocking_read(size)
72
+ trap do
73
+ if can_read?(size)
74
+ yank(size)
75
+ else
76
+ raise ArgumentError, "Unexpected state" if @size or @callback
77
+
78
+ fiber = Fiber.current
79
+ @size = size
80
+ @callback = proc { |data|
81
+ fiber.resume(data)
82
+ }
83
+ Fiber.yield
84
+ end
85
+ end
86
+ end
87
+
88
+ def receive_data(data)
89
+ trap do
90
+ (@buf) << data
91
+
92
+ if @callback and can_read?(@size)
93
+ callback = @callback
94
+ data = yank(@size)
95
+ @callback = @size = nil
96
+ callback.call(data)
97
+ end
98
+ end
99
+ end
100
+
101
+ def connected?
102
+ @connected
103
+ end
104
+
105
+ def connection_completed
106
+ @reconnecting = false
107
+ @connected = true
108
+ succeed
109
+ end
110
+
111
+ def unbind
112
+ # If we disconnect, try to reconnect
113
+ if @connected or !@reconnecting
114
+ EM.add_timer(1) {
115
+ # XXX Connect timeout?
116
+ reconnect @host, @port
117
+ }
118
+ @connected = false
119
+ @reconnecting = true
120
+ end
121
+ end
122
+
123
+ def can_read?(size)
124
+ @buf.size >= @index + size
125
+ end
126
+
127
+ private
128
+
129
+ def yank(len)
130
+ data = @buf.slice(@index, len)
131
+ @index += len
132
+ @index = @buf.size if @index > @buf.size
133
+ if @index >= GARBAGE_BUFFER_SIZE
134
+ @buf = @buf.slice(@index..-1)
135
+ @index = 0
136
+ end
137
+ data
138
+ end
139
+
140
+ end
141
+ end
@@ -0,0 +1,263 @@
1
+ require 'socket'
2
+ require 'getoptlong'
3
+
4
+ class ThriftClient
5
+
6
+ # This is a simplified form of thrift, useful for clients only, and not
7
+ # making any attempt to have good performance. It's intended to be used by
8
+ # small command-line tools that don't want to install a dozen ruby files.
9
+ module Simple
10
+ VERSION_1 = 0x8001
11
+
12
+ # message types
13
+ CALL, REPLY, EXCEPTION = (1..3).to_a
14
+
15
+ # value types
16
+ STOP, VOID, BOOL, BYTE, DOUBLE, _, I16, _, I32, _, I64, STRING, STRUCT, MAP, SET, LIST = (0..15).to_a
17
+
18
+ FORMATS = {
19
+ BYTE => "c",
20
+ DOUBLE => "G",
21
+ I16 => "n",
22
+ I32 => "N",
23
+ }
24
+
25
+ SIZES = {
26
+ BYTE => 1,
27
+ DOUBLE => 8,
28
+ I16 => 2,
29
+ I32 => 4,
30
+ }
31
+
32
+ module ComplexType
33
+ module Extends
34
+ def type_id=(n)
35
+ @type_id = n
36
+ end
37
+
38
+ def type_id
39
+ @type_id
40
+ end
41
+ end
42
+
43
+ module Includes
44
+ def to_i
45
+ self.class.type_id
46
+ end
47
+
48
+ def to_s
49
+ args = self.values.map { |v| self.class.type_id == STRUCT ? v.name : v.to_s }.join(", ")
50
+ "#{self.class.name}.new(#{args})"
51
+ end
52
+ end
53
+ end
54
+
55
+ def self.make_type(type_id, name, *args)
56
+ klass = Struct.new("STT_#{name}", *args)
57
+ klass.send(:extend, ComplexType::Extends)
58
+ klass.send(:include, ComplexType::Includes)
59
+ klass.type_id = type_id
60
+ klass
61
+ end
62
+
63
+ ListType = make_type(LIST, "ListType", :element_type)
64
+ MapType = make_type(MAP, "MapType", :key_type, :value_type)
65
+ SetType = make_type(SET, "SetType", :element_type)
66
+ StructType = make_type(STRUCT, "StructType", :struct_class)
67
+
68
+ class << self
69
+ def pack_value(type, value)
70
+ case type
71
+ when BOOL
72
+ [ value ? 1 : 0 ].pack("c")
73
+ when STRING
74
+ [ value.size, value ].pack("Na*")
75
+ when I64
76
+ [ value >> 32, value & 0xffffffff ].pack("NN")
77
+ when ListType
78
+ [ type.element_type.to_i, value.size ].pack("cN") + value.map { |item| pack_value(type.element_type, item) }.join("")
79
+ when MapType
80
+ [ type.key_type.to_i, type.value_type.to_i, value.size ].pack("ccN") + value.map { |k, v| pack_value(type.key_type, k) + pack_value(type.value_type, v) }.join("")
81
+ when SetType
82
+ [ type.element_type.to_i, value.size ].pack("cN") + value.map { |item| pack_value(type.element_type, item) }.join("")
83
+ when StructType
84
+ value._pack
85
+ else
86
+ [ value ].pack(FORMATS[type])
87
+ end
88
+ end
89
+
90
+ def pack_request(method_name, arg_struct, request_id=0)
91
+ [ VERSION_1, CALL, method_name.to_s.size, method_name.to_s, request_id, arg_struct._pack ].pack("nnNa*Na*")
92
+ end
93
+
94
+ def read_value(s, type)
95
+ case type
96
+ when BOOL
97
+ s.read(1).unpack("c").first != 0
98
+ when STRING
99
+ len = s.read(4).unpack("N").first
100
+ s.read(len)
101
+ when I64
102
+ hi, lo = s.read(8).unpack("NN")
103
+ (hi << 32) | lo
104
+ when LIST
105
+ read_list(s)
106
+ when MAP
107
+ read_map(s)
108
+ when STRUCT
109
+ read_struct(s)
110
+ when ListType
111
+ read_list(s, type.element_type)
112
+ when MapType
113
+ read_map(s, type.key_type, type.value_type)
114
+ when StructType
115
+ read_struct(s, type.struct_class)
116
+ else
117
+ s.read(SIZES[type]).unpack(FORMATS[type]).first
118
+ end
119
+ end
120
+
121
+ def read_list(s, element_type=nil)
122
+ etype, len = s.read(5).unpack("cN")
123
+ expected_type = (element_type and element_type.to_i == etype.to_i) ? element_type : etype
124
+ rv = []
125
+ len.times do
126
+ rv << read_value(s, expected_type)
127
+ end
128
+ rv
129
+ end
130
+
131
+ def read_map(s, key_type=nil, value_type=nil)
132
+ ktype, vtype, len = s.read(6).unpack("ccN")
133
+ rv = {}
134
+ expected_key_type, expected_value_type = if key_type and value_type and key_type.to_i == ktype and value_type.to_i == vtype
135
+ [ key_type, value_type ]
136
+ else
137
+ [ ktype, vtype ]
138
+ end
139
+ len.times do
140
+ key = read_value(s, expected_key_type)
141
+ value = read_value(s, expected_value_type)
142
+ rv[key] = value
143
+ end
144
+ rv
145
+ end
146
+
147
+ def read_struct(s, struct_class=nil)
148
+ rv = struct_class.new()
149
+ while true
150
+ type = s.read(1).unpack("c").first
151
+ return rv if type == STOP
152
+ fid = s.read(2).unpack("n").first
153
+ field = struct_class ? struct_class._fields.find { |f| (f.fid == fid) and (f.type.to_i == type) } : nil
154
+ value = read_value(s, field ? field.type : type)
155
+ rv[field.name] = value if field
156
+ end
157
+ end
158
+
159
+ def read_response(s, rv_class)
160
+ version, message_type, method_name_len = s.read(8).unpack("nnN")
161
+ method_name = s.read(method_name_len)
162
+ seq_id = s.read(4).unpack("N").first
163
+ [ method_name, seq_id, read_struct(s, rv_class).rv ]
164
+ end
165
+ end
166
+
167
+ ## ----------------------------------------
168
+
169
+ class Field
170
+ attr_accessor :name, :type, :fid
171
+
172
+ def initialize(name, type, fid)
173
+ @name = name
174
+ @type = type
175
+ @fid = fid
176
+ end
177
+
178
+ def pack(value)
179
+ value.nil? ? "" : [ type.to_i, fid, ThriftClient::Simple.pack_value(type, value) ].pack("cna*")
180
+ end
181
+ end
182
+
183
+ class ThriftException < RuntimeError
184
+ def initialize(reason)
185
+ @reason = reason
186
+ end
187
+
188
+ def to_s
189
+ "ThriftException(#{@reason.inspect})"
190
+ end
191
+ end
192
+
193
+ module ThriftStruct
194
+ module Include
195
+ def _pack
196
+ self.class._fields.map { |f| f.pack(self[f.name]) }.join + [ STOP ].pack("c")
197
+ end
198
+ end
199
+
200
+ module Extend
201
+ def _fields
202
+ @fields
203
+ end
204
+
205
+ def _fields=(f)
206
+ @fields = f
207
+ end
208
+ end
209
+ end
210
+
211
+ def self.make_struct(name, *fields)
212
+ st_name = "ST_#{name}"
213
+ if Struct.constants.include?(st_name)
214
+ warn "#{caller[0]}: Struct::#{st_name} is already defined; returning original class."
215
+ Struct.const_get(st_name)
216
+ else
217
+ names = fields.map { |f| f.name.to_sym }
218
+ klass = Struct.new(st_name, *names)
219
+ klass.send(:include, ThriftStruct::Include)
220
+ klass.send(:extend, ThriftStruct::Extend)
221
+ klass._fields = fields
222
+ klass
223
+ end
224
+ end
225
+
226
+ class ThriftService
227
+ def initialize(sock)
228
+ @sock = sock
229
+ end
230
+
231
+ def self._arg_structs
232
+ @_arg_structs = {} if @_arg_structs.nil?
233
+ @_arg_structs
234
+ end
235
+
236
+ def self.thrift_method(name, rtype, *args)
237
+ arg_struct = ThriftClient::Simple.make_struct("Args__#{self.name}__#{name}", *args)
238
+ rv_struct = ThriftClient::Simple.make_struct("Retval__#{self.name}__#{name}", ThriftClient::Simple::Field.new(:rv, rtype, 0))
239
+ _arg_structs[name.to_sym] = [ arg_struct, rv_struct ]
240
+
241
+ arg_names = args.map { |a| a.name.to_s }.join(", ")
242
+ class_eval "def #{name}(#{arg_names}); _proxy(:#{name}#{args.size > 0 ? ', ' : ''}#{arg_names}); end"
243
+ end
244
+
245
+ def _proxy(method_name, *args)
246
+ cls = self.class.ancestors.find { |cls| cls.respond_to?(:_arg_structs) and cls._arg_structs[method_name.to_sym] }
247
+ arg_class, rv_class = cls._arg_structs[method_name.to_sym]
248
+ arg_struct = arg_class.new(*args)
249
+ @sock.write(ThriftClient::Simple.pack_request(method_name, arg_struct))
250
+ rv = ThriftClient::Simple.read_response(@sock, rv_class)
251
+ rv[2]
252
+ end
253
+
254
+ # convenience. robey is lazy.
255
+ [[ :field, "Field.new" ], [ :struct, "StructType.new" ],
256
+ [ :list, "ListType.new" ], [ :map, "MapType.new" ]].each do |new_name, old_name|
257
+ class_eval "def self.#{new_name}(*args); ThriftClient::Simple::#{old_name}(*args); end"
258
+ end
259
+
260
+ [ :void, :bool, :byte, :double, :i16, :i32, :i64, :string ].each { |sym| class_eval "def self.#{sym}; ThriftClient::Simple::#{sym.to_s.upcase}; end" }
261
+ end
262
+ end
263
+ end
@@ -1,4 +1,3 @@
1
-
2
1
  module Thrift
3
2
  class BufferedTransport
4
3
  def timeout=(timeout)
data/lib/thrift_client.rb CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  if ENV["ANCIENT_THRIFT"]
3
2
  $LOAD_PATH.unshift("/Users/eweaver/p/twitter/rails/vendor/gems/thrift-751142/lib")
4
3
  $LOAD_PATH.unshift("/Users/eweaver/p/twitter/rails/vendor/gems/thrift-751142/ext")
@@ -8,18 +7,19 @@ else
8
7
  require 'thrift'
9
8
  end
10
9
 
11
- require 'timeout'
12
10
  require 'rubygems'
13
11
  require 'thrift_client/thrift'
12
+ require 'thrift_client/connection'
14
13
 
15
14
  class ThriftClient
15
+
16
16
  class NoServersAvailable < StandardError; end
17
- class GlobalThriftClientTimeout < Timeout::Error; end
18
17
 
19
18
  DEFAULTS = {
20
19
  :protocol => Thrift::BinaryProtocol,
21
20
  :protocol_extra_params => [],
22
- :transport => Thrift::FramedTransport,
21
+ :transport => Thrift::Socket,
22
+ :transport_wrapper => Thrift::FramedTransport,
23
23
  :randomize_server_list => true,
24
24
  :exception_classes => [
25
25
  IOError,
@@ -52,8 +52,7 @@ Valid optional parameters are:
52
52
  <tt>:retries</tt>:: How many times to retry a request. Defaults to the number of servers defined.
53
53
  <tt>:server_retry_period</tt>:: How many seconds to wait before trying to reconnect after marking all servers as down. Defaults to <tt>1</tt>. Set to <tt>nil</tt> to retry endlessly.
54
54
  <tt>:server_max_requests</tt>:: How many requests to perform before moving on to the next server in the pool, regardless of error status. Defaults to <tt>nil</tt> (no limit).
55
- <tt>:global_timeout</tt>:: Specify the timeout for all connections made. Defaults to being disabled.
56
- <tt>:timeout</tt>:: Specify the default timeout in seconds per connection. Defaults to <tt>1</tt>.
55
+ <tt>:timeout</tt>:: Specify the default timeout in seconds. Defaults to <tt>1</tt>.
57
56
  <tt>:timeout_overrides</tt>:: Specify additional timeouts on a per-method basis, in seconds. Only works with <tt>Thrift::BufferedTransport</tt>.
58
57
  <tt>:defaults</tt>:: Specify default values to return on a per-method basis, if <tt>:raise</tt> is set to false.
59
58
 
@@ -66,17 +65,16 @@ Valid optional parameters are:
66
65
  @retries = options[:retries] || @server_list.size
67
66
 
68
67
  if @options[:timeout_overrides].any?
69
- if @options[:transport].instance_methods.include?("timeout=")
68
+ if (@options[:transport_wrapper] || @options[:transport]).method_defined?(:timeout=)
70
69
  @set_timeout = true
71
70
  else
72
- warn "ThriftClient: Timeout overrides have no effect with with transport type #{@options[:transport]}"
71
+ warn "ThriftClient: Timeout overrides have no effect with with transport type #{(@options[:transport_wrapper] || @options[:transport])}"
73
72
  end
74
73
  end
75
74
 
76
75
  @request_count = 0
77
76
  @max_requests = @options[:server_max_requests]
78
77
  @retry_period = @options[:server_retry_period]
79
- @global_timeout = @options[:global_timeout] || 0
80
78
  rebuild_live_server_list!
81
79
 
82
80
  @client_class.instance_methods.each do |method_name|
@@ -88,23 +86,18 @@ Valid optional parameters are:
88
86
 
89
87
  # Force the client to connect to the server.
90
88
  def connect!
91
- server = next_server
92
- host, port = server.to_s.split(":")
93
- raise ArgumentError, 'Servers must be in the form "host:port"' unless host and port
94
-
95
- @transport = @options[:transport].new(
96
- Thrift::Socket.new(host, port.to_i, @options[:timeout]))
97
- @transport.open
98
- @current_server = server
99
- @client = @client_class.new(@options[:protocol].new(@transport, *@options[:protocol_extra_params]))
100
- rescue Thrift::TransportException
89
+ @current_server = next_server
90
+ @connection = Connection::Factory.create(@options[:transport], @options[:transport_wrapper], @current_server, @options[:timeout])
91
+ @connection.connect!
92
+ @client = @client_class.new(@options[:protocol].new(@connection.transport, *@options[:protocol_extra_params]))
93
+ rescue Thrift::TransportException, Errno::ECONNREFUSED
101
94
  @transport.close rescue nil
102
95
  retry
103
96
  end
104
97
 
105
98
  # Force the client to disconnect from the server.
106
99
  def disconnect!(keep = true)
107
- @transport.close rescue nil
100
+ @connection.close rescue nil
108
101
 
109
102
  # Keep live servers in the list if we have a retry period. Otherwise,
110
103
  # always eject, because we will always re-add them.
@@ -119,16 +112,26 @@ Valid optional parameters are:
119
112
 
120
113
  private
121
114
 
122
- def proxy(method_name, *args)
123
- Timeout.timeout(@global_timeout, GlobalThriftClientTimeout) do
124
- raw_proxy(method_name, *args)
115
+ def next_server
116
+ if @retry_period
117
+ rebuild_live_server_list! if Time.now > @last_rebuild + @retry_period
118
+ raise NoServersAvailable, "No live servers in #{@server_list.inspect} since #{@last_rebuild.inspect}." if @live_server_list.empty?
119
+ elsif @live_server_list.empty?
120
+ rebuild_live_server_list!
121
+ end
122
+ @live_server_list.pop
123
+ end
124
+
125
+ def rebuild_live_server_list!
126
+ @last_rebuild = Time.now
127
+ if @options[:randomize_server_list]
128
+ @live_server_list = @server_list.sort_by { rand }
129
+ else
130
+ @live_server_list = @server_list.dup
125
131
  end
126
- rescue GlobalThriftClientTimeout => e
127
- disconnect!(false)
128
- raise e
129
132
  end
130
133
 
131
- def raw_proxy(method_name, *args)
134
+ def proxy(method_name, *args)
132
135
  disconnect! if @max_requests and @request_count >= @max_requests
133
136
  connect! unless @client
134
137
 
@@ -148,27 +151,8 @@ Valid optional parameters are:
148
151
  @client.timeout = @options[:timeout_overrides][method_name.to_sym] || @options[:timeout]
149
152
  end
150
153
 
151
- def handle_exception(e, method_name, args)
154
+ def handle_exception(e, method_name, args=nil)
152
155
  raise e if @options[:raise]
153
156
  @options[:defaults][method_name.to_sym]
154
157
  end
155
-
156
- def next_server
157
- if @retry_period
158
- rebuild_live_server_list! if Time.now > @last_rebuild + @retry_period
159
- raise NoServersAvailable, "No live servers in #{@server_list.inspect} since #{@last_rebuild.inspect}." if @live_server_list.empty?
160
- elsif @live_server_list.empty?
161
- rebuild_live_server_list!
162
- end
163
- @live_server_list.pop
164
- end
165
-
166
- def rebuild_live_server_list!
167
- @last_rebuild = Time.now
168
- if @options[:randomize_server_list]
169
- @live_server_list = @server_list.sort_by { rand }
170
- else
171
- @live_server_list = @server_list.dup
172
- end
173
- end
174
158
  end
@@ -0,0 +1,77 @@
1
+ #
2
+ # Autogenerated by Thrift
3
+ #
4
+ # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5
+ #
6
+
7
+ require 'thrift'
8
+
9
+ module Greeter
10
+ class Client
11
+ include ::Thrift::Client
12
+
13
+ def greeting(name)
14
+ send_greeting(name)
15
+ return recv_greeting()
16
+ end
17
+
18
+ def send_greeting(name)
19
+ send_message('greeting', Greeting_args, :name => name)
20
+ end
21
+
22
+ def recv_greeting()
23
+ result = receive_message(Greeting_result)
24
+ return result.success unless result.success.nil?
25
+ raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'greeting failed: unknown result')
26
+ end
27
+
28
+ end
29
+
30
+ class Processor
31
+ include ::Thrift::Processor
32
+
33
+ def process_greeting(seqid, iprot, oprot)
34
+ args = read_args(iprot, Greeting_args)
35
+ result = Greeting_result.new()
36
+ result.success = @handler.greeting(args.name)
37
+ write_result(result, oprot, 'greeting', seqid)
38
+ end
39
+
40
+ end
41
+
42
+ # HELPER FUNCTIONS AND STRUCTURES
43
+
44
+ class Greeting_args
45
+ include ::Thrift::Struct
46
+ NAME = 1
47
+
48
+ ::Thrift::Struct.field_accessor self, :name
49
+ FIELDS = {
50
+ NAME => {:type => ::Thrift::Types::STRING, :name => 'name'}
51
+ }
52
+
53
+ def struct_fields; FIELDS; end
54
+
55
+ def validate
56
+ end
57
+
58
+ end
59
+
60
+ class Greeting_result
61
+ include ::Thrift::Struct
62
+ SUCCESS = 0
63
+
64
+ ::Thrift::Struct.field_accessor self, :success
65
+ FIELDS = {
66
+ SUCCESS => {:type => ::Thrift::Types::STRING, :name => 'success'}
67
+ }
68
+
69
+ def struct_fields; FIELDS; end
70
+
71
+ def validate
72
+ end
73
+
74
+ end
75
+
76
+ end
77
+
@@ -0,0 +1,3 @@
1
+ service Greeter {
2
+ string greeting(1:string name)
3
+ }
@@ -0,0 +1,40 @@
1
+ module Greeter
2
+ class Handler
3
+ def greeting(name)
4
+ "hello there #{name}!"
5
+ end
6
+ end
7
+
8
+ class Server
9
+ def initialize(port)
10
+ @port = port
11
+ handler = Greeter::Handler.new
12
+ processor = Greeter::Processor.new(handler)
13
+ transport = Thrift::ServerSocket.new("127.0.0.1", port)
14
+ transportFactory = Thrift::FramedTransportFactory.new()
15
+ @server = Thrift::SimpleServer.new(processor, transport, transportFactory)
16
+ end
17
+
18
+ def serve
19
+ @server.serve()
20
+ end
21
+ end
22
+
23
+ # client:
24
+ # trans = Thrift::HTTPClientTransport.new("http://127.0.0.1:9292/greeter")
25
+ # prot = Thrift::BinaryProtocol.new(trans)
26
+ # c = Greeter::Client.new(prot)
27
+ class HTTPServer
28
+ def initialize(uri)
29
+ uri = URI.parse(uri)
30
+ handler = Greeter::Handler.new
31
+ processor = Greeter::Processor.new(handler)
32
+ path = uri.path[1..-1]
33
+ @server = Thrift::MongrelHTTPServer.new(processor, :port => uri.port, :ip => uri.host, :path => path)
34
+ end
35
+
36
+ def serve
37
+ @server.serve()
38
+ end
39
+ end
40
+ end
data/test/simple_test.rb CHANGED
@@ -2,18 +2,18 @@
2
2
  require "#{File.dirname(__FILE__)}/test_helper"
3
3
 
4
4
  class SimpleTest < Test::Unit::TestCase
5
-
5
+
6
6
  S = ThriftClient::Simple
7
7
  S.make_struct("Example", S::Field.new(:name, S::STRING, 1))
8
8
  S.make_struct("Args")
9
9
  S.make_struct("Retval", S::Field.new(:rv, S::I32, 0))
10
-
10
+
11
11
  def test_definition
12
12
  assert Struct::ST_Example
13
13
  assert Struct::ST_Args
14
14
  assert Struct::ST_Retval
15
15
  end
16
-
16
+
17
17
  ## Encoding
18
18
 
19
19
  def test_boolean_encoding
@@ -69,7 +69,7 @@ class SimpleTest < Test::Unit::TestCase
69
69
  assert_equal "\x80\x01\x00\x01\x00\x00\x00\x09getHeight\x00\x00\x00\x17\x00",
70
70
  S.pack_request("getHeight", Struct::ST_Args.new, 23)
71
71
  end
72
-
72
+
73
73
  ## Decoding
74
74
 
75
75
  def test_boolean_decoding
@@ -133,5 +133,5 @@ class SimpleTest < Test::Unit::TestCase
133
133
  StringIO.new("\x80\x01\x00\x02\x00\x00\x00\x09getHeight\x00\x00\x00\xff\x08\x00\x00\x00\x00\x00\x01\x00"),
134
134
  Struct::ST_Retval)
135
135
  end
136
-
136
+
137
137
  end
data/test/test_helper.rb CHANGED
@@ -4,5 +4,9 @@ require 'benchmark'
4
4
  $LOAD_PATH << "#{File.expand_path(File.dirname(__FILE__))}/../lib"
5
5
  require 'thrift_client'
6
6
  require 'thrift_client/simple'
7
- require 'scribe'
7
+
8
+ $LOAD_PATH << File.expand_path(File.dirname(__FILE__))
9
+ require 'greeter/greeter'
10
+ require 'greeter/server'
11
+
8
12
  begin; require 'ruby-debug'; rescue LoadError; end
@@ -0,0 +1,54 @@
1
+ require "#{File.dirname(__FILE__)}/test_helper"
2
+ require "thrift/server/mongrel_http_server"
3
+
4
+ class ThriftClientHTTPTest < Test::Unit::TestCase
5
+
6
+ def setup
7
+ @servers = ["http://127.0.0.1:1461/greeter", "http://127.0.0.1:1462/greeter", "http://127.0.0.1:1463/greeter"]
8
+ @socket = 1461
9
+ @timeout = 0.2
10
+ @options = {:protocol_extra_params => [false]}
11
+ @pid = Process.fork do
12
+ Signal.trap("INT") { exit }
13
+ Greeter::HTTPServer.new(@servers.last).serve
14
+ end
15
+ # Need to give the child process a moment to open the listening socket or
16
+ # we get occasional "could not connect" errors in tests.
17
+ sleep 0.05
18
+ end
19
+
20
+ def teardown
21
+ Process.kill("INT", @pid)
22
+ Process.wait
23
+ end
24
+
25
+ def test_bad_uri
26
+ assert_raises URI::InvalidURIError do
27
+ @options.merge!({ :protocol => Thrift::BinaryProtocol, :transport => Thrift::HTTPClientTransport })
28
+ ThriftClient.new(Greeter::Client, "127.0.0.1:1463", @options).greeting("someone")
29
+ end
30
+ end
31
+
32
+ def test_bad_uri_no_http
33
+ assert_raises ArgumentError do
34
+ @options.merge!({ :protocol => Thrift::BinaryProtocol, :transport => Thrift::HTTPClientTransport })
35
+ ThriftClient.new(Greeter::Client, "//127.0.0.1:1463", @options).greeting("someone")
36
+ end
37
+ end
38
+
39
+ def test_valid_server
40
+ assert_nothing_raised do
41
+ @options.merge!({ :protocol => Thrift::BinaryProtocol, :transport => Thrift::HTTPClientTransport })
42
+ ThriftClient.new(Greeter::Client, "http://127.0.0.1:1463/greeter", @options).greeting("someone")
43
+ end
44
+ end
45
+
46
+ def test_non_random_fall_through
47
+ @servers = ["http://127.0.0.1:1463/greeter", "http://127.0.0.1:1461/greeter", "http://127.0.0.1:1462/greeter"]
48
+ assert_nothing_raised do
49
+ @options.merge!({ :protocol => Thrift::BinaryProtocol, :transport => Thrift::HTTPClientTransport })
50
+ ThriftClient.new(Greeter::Client, @servers, @options.merge(:randomize_server_list => false)).greeting("someone")
51
+ end
52
+ end
53
+
54
+ end
@@ -1,58 +1,74 @@
1
1
  require "#{File.dirname(__FILE__)}/test_helper"
2
2
 
3
3
  class ThriftClientTest < Test::Unit::TestCase
4
+
4
5
  def setup
5
- @entry = [ScribeThrift::LogEntry.new(:message => "something", :category => "thrift_client")]
6
6
  @servers = ["127.0.0.1:1461", "127.0.0.1:1462", "127.0.0.1:1463"]
7
7
  @socket = 1461
8
8
  @timeout = 0.2
9
9
  @options = {:protocol_extra_params => [false]}
10
+ @pid = Process.fork do
11
+ Signal.trap("INT") { exit }
12
+ Greeter::Server.new("1463").serve
13
+ end
14
+ # Need to give the child process a moment to open the listening socket or
15
+ # we get occasional "could not connect" errors in tests.
16
+ sleep 0.05
17
+ end
18
+
19
+ def teardown
20
+ Process.kill("INT", @pid)
21
+ Process.wait
10
22
  end
11
23
 
12
24
  def test_live_server
13
25
  assert_nothing_raised do
14
- ThriftClient.new(ScribeThrift::Client, @servers.last, @options).Log(@entry)
26
+ ThriftClient.new(Greeter::Client, @servers.last, @options).greeting("someone")
15
27
  end
16
28
  end
17
29
 
18
30
  def test_non_random_fall_through
19
31
  assert_nothing_raised do
20
- ThriftClient.new(ScribeThrift::Client, @servers, @options.merge(:randomize_server_list => false)).Log(@entry)
32
+ ThriftClient.new(Greeter::Client, @servers, @options.merge(:randomize_server_list => false)).greeting("someone")
21
33
  end
22
34
  end
23
35
 
24
36
  def test_dont_raise
25
37
  assert_nothing_raised do
26
- ThriftClient.new(ScribeThrift::Client, @servers.first, @options.merge(:raise => false)).Log(@entry)
38
+ ThriftClient.new(Greeter::Client, @servers.first, @options.merge(:raise => false)).greeting("someone")
27
39
  end
28
40
  end
29
41
 
30
42
  def test_dont_raise_with_defaults
31
- client = ThriftClient.new(ScribeThrift::Client, @servers.first, @options.merge(:raise => false, :defaults => {:Log => 1}))
32
- assert_equal 1, client.Log(@entry)
43
+ client = ThriftClient.new(Greeter::Client, @servers.first, @options.merge(:raise => false, :defaults => {:greeting => 1}))
44
+ assert_equal 1, client.greeting
33
45
  end
34
46
 
35
47
  def test_defaults_dont_override_no_method_error
36
- client = ThriftClient.new(ScribeThrift::Client, @servers, @options.merge(:raise => false, :defaults => {:Missing => 2}))
37
- assert_raises(NoMethodError) { client.Missing(@entry) }
48
+ client = ThriftClient.new(Greeter::Client, @servers, @options.merge(:raise => false, :defaults => {:Missing => 2}))
49
+ assert_raises(NoMethodError) { client.Missing }
38
50
  end
39
51
 
40
52
  def test_random_fall_through
41
53
  assert_nothing_raised do
42
- 10.times { ThriftClient.new(ScribeThrift::Client, @servers, @options).Log(@entry) }
54
+ 10.times do
55
+ client = ThriftClient.new(Greeter::Client, @servers, @options)
56
+ client.greeting("someone")
57
+ client.disconnect!
58
+ end
43
59
  end
44
60
  end
45
61
 
46
62
  def test_lazy_connection
47
63
  assert_nothing_raised do
48
- ThriftClient.new(ScribeThrift::Client, @servers[0,2])
64
+ ThriftClient.new(Greeter::Client, @servers[0,2])
49
65
  end
50
66
  end
51
67
 
52
68
  def test_no_servers_eventually_raise
53
- client = ThriftClient.new(ScribeThrift::Client, @servers[0,2], @options)
69
+ client = ThriftClient.new(Greeter::Client, @servers[0,2], @options)
54
70
  assert_raises(ThriftClient::NoServersAvailable) do
55
- client.Log(@entry)
71
+ client.greeting("someone")
56
72
  client.disconnect!
57
73
  end
58
74
  end
@@ -61,13 +77,12 @@ class ThriftClientTest < Test::Unit::TestCase
61
77
  stub_server(@socket) do |socket|
62
78
  measurement = Benchmark.measure do
63
79
  assert_raises(Thrift::TransportException) do
64
- ThriftClient.new(ScribeThrift::Client, "127.0.0.1:#{@socket}",
80
+ ThriftClient.new(Greeter::Client, "127.0.0.1:#{@socket}",
65
81
  @options.merge(:timeout => @timeout)
66
- ).Log(@entry)
82
+ ).greeting("someone")
67
83
  end
68
84
  end
69
- assert((measurement.real > @timeout - 0.01), "#{measurement.real} < #{@timeout}")
70
- assert((measurement.real < @timeout + 0.01), "#{measurement.real} > #{@timeout}")
85
+ assert((measurement.real > @timeout), "#{measurement.real} < #{@timeout}")
71
86
  end
72
87
  end
73
88
 
@@ -75,13 +90,12 @@ class ThriftClientTest < Test::Unit::TestCase
75
90
  stub_server(@socket) do |socket|
76
91
  measurement = Benchmark.measure do
77
92
  assert_raises(Thrift::TransportException) do
78
- ThriftClient.new(ScribeThrift::Client, "127.0.0.1:#{@socket}",
79
- @options.merge(:timeout => @timeout, :transport => Thrift::BufferedTransport)
80
- ).Log(@entry)
93
+ ThriftClient.new(Greeter::Client, "127.0.0.1:#{@socket}",
94
+ @options.merge(:timeout => @timeout, :transport_wrapper => Thrift::BufferedTransport)
95
+ ).greeting("someone")
81
96
  end
82
97
  end
83
- assert((measurement.real > @timeout - 0.01), "#{measurement.real} < #{@timeout}")
84
- assert((measurement.real < @timeout + 0.01), "#{measurement.real} > #{@timeout}")
98
+ assert((measurement.real > @timeout), "#{measurement.real} < #{@timeout}")
85
99
  end
86
100
  end
87
101
 
@@ -91,30 +105,29 @@ class ThriftClientTest < Test::Unit::TestCase
91
105
  stub_server(@socket) do |socket|
92
106
  measurement = Benchmark.measure do
93
107
  assert_raises(Thrift::TransportException) do
94
- ThriftClient.new(ScribeThrift::Client, "127.0.0.1:#{@socket}",
95
- @options.merge(:timeout => @timeout, :timeout_overrides => {:Log => log_timeout}, :transport => Thrift::BufferedTransport)
96
- ).Log(@entry)
108
+ ThriftClient.new(Greeter::Client, "127.0.0.1:#{@socket}",
109
+ @options.merge(:timeout => @timeout, :timeout_overrides => {:greeting => log_timeout}, :transport_wrapper => Thrift::BufferedTransport)
110
+ ).greeting("someone")
97
111
  end
98
112
  end
99
- assert((measurement.real > log_timeout - 0.01), "#{measurement.real} < #{log_timeout }")
100
- assert((measurement.real < log_timeout + 0.01), "#{measurement.real} > #{log_timeout}")
113
+ assert((measurement.real > log_timeout), "#{measurement.real} < #{log_timeout}")
101
114
  end
102
115
  end
103
116
 
104
117
  def test_retry_period
105
- client = ThriftClient.new(ScribeThrift::Client, @servers[0,2], @options.merge(:server_retry_period => 1))
106
- assert_raises(ThriftClient::NoServersAvailable) { client.Log(@entry) }
118
+ client = ThriftClient.new(Greeter::Client, @servers[0,2], @options.merge(:server_retry_period => 1))
119
+ assert_raises(ThriftClient::NoServersAvailable) { client.greeting("someone") }
107
120
  sleep 1.1
108
- assert_raises(ThriftClient::NoServersAvailable) { client.Log(@entry) }
121
+ assert_raises(ThriftClient::NoServersAvailable) { client.greeting("someone") }
109
122
  end
110
-
123
+
111
124
  def test_server_max_requests
112
- client = ThriftClient.new(ScribeThrift::Client, @servers, @options.merge(:server_max_requests => 2))
113
- client.Log(@entry)
125
+ client = ThriftClient.new(Greeter::Client, @servers, @options.merge(:server_max_requests => 2))
126
+ client.greeting("someone")
114
127
  internal_client = client.client
115
- client.Log(@entry)
128
+ client.greeting("someone")
116
129
  assert_equal internal_client, client.client
117
- client.Log(@entry)
130
+ client.greeting("someone")
118
131
  assert_not_equal internal_client, client.client
119
132
  end
120
133
 
@@ -2,22 +2,24 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{thrift_client}
5
- s.version = "0.3.3"
5
+ s.version = "0.4.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0.8") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Evan Weaver"]
9
- s.date = %q{2010-01-11}
9
+ s.cert_chain = ["/Users/ryan/.gemkeys/gem-public_cert.pem"]
10
+ s.date = %q{2010-02-18}
10
11
  s.description = %q{A Thrift client wrapper that encapsulates some common failover behavior.}
11
12
  s.email = %q{}
12
- s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README", "lib/thrift_client.rb", "lib/thrift_client/thrift.rb"]
13
- s.files = ["CHANGELOG", "LICENSE", "Manifest", "README", "Rakefile", "lib/thrift_client.rb", "lib/thrift_client/thrift.rb", "test/test_helper.rb", "test/thrift_client_test.rb", "thrift_client.gemspec", "test/simple_test.rb"]
13
+ s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.rdoc", "lib/thrift_client.rb", "lib/thrift_client/connection.rb", "lib/thrift_client/connection/base.rb", "lib/thrift_client/connection/factory.rb", "lib/thrift_client/connection/http.rb", "lib/thrift_client/connection/socket.rb", "lib/thrift_client/event_machine.rb", "lib/thrift_client/simple.rb", "lib/thrift_client/thrift.rb"]
14
+ s.files = ["CHANGELOG", "LICENSE", "Manifest", "README.rdoc", "Rakefile", "lib/thrift_client.rb", "lib/thrift_client/connection.rb", "lib/thrift_client/connection/base.rb", "lib/thrift_client/connection/factory.rb", "lib/thrift_client/connection/http.rb", "lib/thrift_client/connection/socket.rb", "lib/thrift_client/event_machine.rb", "lib/thrift_client/simple.rb", "lib/thrift_client/thrift.rb", "test/greeter/greeter.rb", "test/greeter/greeter.thrift", "test/greeter/server.rb", "test/simple_test.rb", "test/test_helper.rb", "test/thrift_client_http_test.rb", "test/thrift_client_test.rb", "thrift_client.gemspec"]
14
15
  s.homepage = %q{http://blog.evanweaver.com/files/doc/fauna/thrift_client/}
15
- s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Thrift_client", "--main", "README"]
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Thrift_client", "--main", "README.rdoc"]
16
17
  s.require_paths = ["lib"]
17
18
  s.rubyforge_project = %q{fauna}
18
19
  s.rubygems_version = %q{1.3.5}
20
+ s.signing_key = %q{/Users/ryan/.gemkeys/gem-private_key.pem}
19
21
  s.summary = %q{A Thrift client wrapper that encapsulates some common failover behavior.}
20
- s.test_files = ["test/simple_test.rb", "test/test_helper.rb", "test/thrift_client_test.rb"]
22
+ s.test_files = ["test/simple_test.rb", "test/test_helper.rb", "test/thrift_client_http_test.rb", "test/thrift_client_test.rb"]
21
23
 
22
24
  if s.respond_to? :specification_version then
23
25
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
data.tar.gz.sig ADDED
Binary file
metadata CHANGED
@@ -1,15 +1,36 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thrift_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Weaver
8
8
  autorequire:
9
9
  bindir: bin
10
- cert_chain: []
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMQ0wCwYDVQQDDARyeWFu
14
+ MRswGQYKCZImiZPyLGQBGRYLdGhlcnlhbmtpbmcxEzARBgoJkiaJk/IsZAEZFgNj
15
+ b20wHhcNMTAwMTA4MTc1MDM0WhcNMTEwMTA4MTc1MDM0WjBBMQ0wCwYDVQQDDARy
16
+ eWFuMRswGQYKCZImiZPyLGQBGRYLdGhlcnlhbmtpbmcxEzARBgoJkiaJk/IsZAEZ
17
+ FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDLPp+0PtRT3qCI
18
+ 02sMsADSn7Uf1GpyXUtk4Fb94LqUO6Scl91YDmbFMpjzrQwQvBYMIVreWcwSish6
19
+ nip6WEk9lqXcOeDmex/qY2/FVXG8ffqjFHiNiN9vpWrWj5VMICequ+ftzWLKsPIS
20
+ DGJ4o+Z6wEYRuirgaRPCYAUDPglsaqctJ56wPuycryMe5+ApSkOS9iLWMprQKEAq
21
+ j2R2OBV0dSARdbtzuKwrP7sLDo7uPa0egFBUlcZ+nujGr4LvmpryB8scNRNmZK1w
22
+ 1rEI7O06CbULj08qYxEhnKmFE7LbBoN/HrmvZLVQK5mWuiZQhtmJuhBfStJsaDux
23
+ 5tBEkYZVAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
24
+ BBSnLarDEo5eBE2arSMrBdOOhtrnPTANBgkqhkiG9w0BAQUFAAOCAQEANER07s4K
25
+ Pvc1DSduliRDMUax/VSfLzDTtTAQwuSAPDrWAYXKugcJtOZOXjDbGL7c5zoWmy9u
26
+ Fn5vEVdm/93J+84D/IMaaof3BwX/NNEYH01CeZEIGMfc5AFFha7dabzP/uiPpb/c
27
+ GSvomC9IzyN37+eWwOS16cC+5XnBT6KRCaXYg2Fh6WpTgde67OVgXr4Q58HXlaZ+
28
+ /2BB3wq9lZ4JskvlpYpYnlPAUyiyc6R2Mjts1pURz5nkW4SuS7Kd1KCOOyr1McDH
29
+ VP12sTSjJclmI17BjDGQpAF0n9v5ExhJxWpeOjeBUPQsOin3ypEM1KkckLmOKvH6
30
+ zyKMYVRO0z/58g==
31
+ -----END CERTIFICATE-----
11
32
 
12
- date: 2010-01-11 00:00:00 -08:00
33
+ date: 2010-02-18 00:00:00 -08:00
13
34
  default_executable:
14
35
  dependencies:
15
36
  - !ruby/object:Gem::Dependency
@@ -31,18 +52,37 @@ extensions: []
31
52
  extra_rdoc_files:
32
53
  - CHANGELOG
33
54
  - LICENSE
34
- - README
55
+ - README.rdoc
35
56
  - lib/thrift_client.rb
57
+ - lib/thrift_client/connection.rb
58
+ - lib/thrift_client/connection/base.rb
59
+ - lib/thrift_client/connection/factory.rb
60
+ - lib/thrift_client/connection/http.rb
61
+ - lib/thrift_client/connection/socket.rb
62
+ - lib/thrift_client/event_machine.rb
63
+ - lib/thrift_client/simple.rb
36
64
  - lib/thrift_client/thrift.rb
37
65
  files:
38
66
  - CHANGELOG
39
67
  - LICENSE
40
68
  - Manifest
41
- - README
69
+ - README.rdoc
42
70
  - Rakefile
43
71
  - lib/thrift_client.rb
72
+ - lib/thrift_client/connection.rb
73
+ - lib/thrift_client/connection/base.rb
74
+ - lib/thrift_client/connection/factory.rb
75
+ - lib/thrift_client/connection/http.rb
76
+ - lib/thrift_client/connection/socket.rb
77
+ - lib/thrift_client/event_machine.rb
78
+ - lib/thrift_client/simple.rb
44
79
  - lib/thrift_client/thrift.rb
80
+ - test/greeter/greeter.rb
81
+ - test/greeter/greeter.thrift
82
+ - test/greeter/server.rb
83
+ - test/simple_test.rb
45
84
  - test/test_helper.rb
85
+ - test/thrift_client_http_test.rb
46
86
  - test/thrift_client_test.rb
47
87
  - thrift_client.gemspec
48
88
  has_rdoc: true
@@ -56,7 +96,7 @@ rdoc_options:
56
96
  - --title
57
97
  - Thrift_client
58
98
  - --main
59
- - README
99
+ - README.rdoc
60
100
  require_paths:
61
101
  - lib
62
102
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -81,4 +121,5 @@ summary: A Thrift client wrapper that encapsulates some common failover behavior
81
121
  test_files:
82
122
  - test/simple_test.rb
83
123
  - test/test_helper.rb
124
+ - test/thrift_client_http_test.rb
84
125
  - test/thrift_client_test.rb
metadata.gz.sig ADDED
@@ -0,0 +1,3 @@
1
+ w�
2
+ � ����_e�@j ~C�q�Kv�)� y k�4����1հ��o�M�_��3,^�&ȯ0i��-ħ�Ve�`�D�x5&��
3
+ 9b�KŮ��c4�uX�Z�m{��U��:'�ٟG�֔�%9�D��0�u���-v�Ma��ֹ��͗"n����t�pN�1֊�2�3�E�\u����֕�ʹ��Q�<I�Ky��}{A�