thrift_client 0.4.0 → 0.4.1
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 +2 -0
- data/Manifest +3 -0
- data/README.rdoc +1 -1
- data/lib/thrift_client/abstract_thrift_client.rb +212 -0
- data/lib/thrift_client/connection/base.rb +2 -3
- data/lib/thrift_client/connection/factory.rb +3 -3
- data/lib/thrift_client/connection/socket.rb +1 -1
- data/lib/thrift_client/event_machine.rb +13 -9
- data/lib/thrift_client.rb +8 -121
- data/test/multiple_working_servers_test.rb +112 -0
- data/test/thrift_client_test.rb +21 -3
- data/thrift_client.gemspec +6 -8
- metadata +24 -31
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -3
data/CHANGELOG
CHANGED
data/Manifest
CHANGED
@@ -4,6 +4,7 @@ Manifest
|
|
4
4
|
README.rdoc
|
5
5
|
Rakefile
|
6
6
|
lib/thrift_client.rb
|
7
|
+
lib/thrift_client/abstract_thrift_client.rb
|
7
8
|
lib/thrift_client/connection.rb
|
8
9
|
lib/thrift_client/connection/base.rb
|
9
10
|
lib/thrift_client/connection/factory.rb
|
@@ -15,7 +16,9 @@ lib/thrift_client/thrift.rb
|
|
15
16
|
test/greeter/greeter.rb
|
16
17
|
test/greeter/greeter.thrift
|
17
18
|
test/greeter/server.rb
|
19
|
+
test/multiple_working_servers_test.rb
|
18
20
|
test/simple_test.rb
|
19
21
|
test/test_helper.rb
|
20
22
|
test/thrift_client_http_test.rb
|
21
23
|
test/thrift_client_test.rb
|
24
|
+
thrift_client.gemspec
|
data/README.rdoc
CHANGED
@@ -7,7 +7,7 @@ A Thrift client wrapper that encapsulates some common failover behavior.
|
|
7
7
|
|
8
8
|
Copyright 2009 Twitter, Inc. See included LICENSE file.
|
9
9
|
|
10
|
-
The public certificate for this gem is here[http://
|
10
|
+
The public certificate for this gem is here[http://blog.evanweaver.com/files/evan_weaver-original-public_cert.pem].
|
11
11
|
|
12
12
|
== Features
|
13
13
|
|
@@ -0,0 +1,212 @@
|
|
1
|
+
class AbstractThriftClient
|
2
|
+
|
3
|
+
DEFAULTS = {
|
4
|
+
:protocol => Thrift::BinaryProtocol,
|
5
|
+
:protocol_extra_params => [],
|
6
|
+
:transport => Thrift::Socket,
|
7
|
+
:transport_wrapper => Thrift::FramedTransport,
|
8
|
+
:raise => true,
|
9
|
+
:defaults => {}
|
10
|
+
}.freeze
|
11
|
+
|
12
|
+
attr_reader :client, :client_class, :current_server, :server_list, :options, :client_methods
|
13
|
+
|
14
|
+
def initialize(client_class, servers, options = {})
|
15
|
+
@options = DEFAULTS.merge(options)
|
16
|
+
@client_class = client_class
|
17
|
+
@server_list = Array(servers)
|
18
|
+
@current_server = @server_list.first
|
19
|
+
|
20
|
+
@client_methods = []
|
21
|
+
@client_class.instance_methods.each do |method_name|
|
22
|
+
if method_name =~ /^recv_(.*)$/
|
23
|
+
instance_eval("def #{$1}(*args); handled_proxy(:'#{$1}', *args); end", __FILE__, __LINE__)
|
24
|
+
@client_methods << $1
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Force the client to connect to the server. Not necessary to be
|
30
|
+
# called as the connection will be made on the first RPC method
|
31
|
+
# call.
|
32
|
+
def connect!
|
33
|
+
@connection = Connection::Factory.create(@options[:transport], @options[:transport_wrapper], @current_server, @options[:timeout])
|
34
|
+
@connection.connect!
|
35
|
+
@client = @client_class.new(@options[:protocol].new(@connection.transport, *@options[:protocol_extra_params]))
|
36
|
+
rescue Thrift::TransportException, Errno::ECONNREFUSED => e
|
37
|
+
@transport.close rescue nil
|
38
|
+
raise e
|
39
|
+
end
|
40
|
+
|
41
|
+
def disconnect!
|
42
|
+
@connection.close rescue nil
|
43
|
+
@client = nil
|
44
|
+
@current_server = nil
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
def handled_proxy(method_name, *args)
|
49
|
+
proxy(method_name, *args)
|
50
|
+
rescue Exception => e
|
51
|
+
handle_exception(e, method_name, args)
|
52
|
+
end
|
53
|
+
|
54
|
+
def proxy(method_name, *args)
|
55
|
+
connect! unless @client
|
56
|
+
send_rpc(method_name, *args)
|
57
|
+
end
|
58
|
+
|
59
|
+
def send_rpc(method_name, *args)
|
60
|
+
@client.send(method_name, *args)
|
61
|
+
end
|
62
|
+
|
63
|
+
def disconnect_on_error!
|
64
|
+
@connection.close rescue nil
|
65
|
+
@client = nil
|
66
|
+
@current_server = nil
|
67
|
+
end
|
68
|
+
|
69
|
+
def handle_exception(e, method_name, args=nil)
|
70
|
+
raise e if @options[:raise]
|
71
|
+
@options[:defaults][method_name.to_sym]
|
72
|
+
end
|
73
|
+
|
74
|
+
module RetryingThriftClient
|
75
|
+
DISCONNECT_ERRORS = [
|
76
|
+
IOError,
|
77
|
+
Thrift::Exception,
|
78
|
+
Thrift::ProtocolException,
|
79
|
+
Thrift::ApplicationException,
|
80
|
+
Thrift::TransportException
|
81
|
+
].freeze
|
82
|
+
|
83
|
+
RETRYING_DEFAULTS = {
|
84
|
+
:exception_classes => DISCONNECT_ERRORS,
|
85
|
+
:randomize_server_list => true,
|
86
|
+
:retries => nil,
|
87
|
+
:server_retry_period => 1,
|
88
|
+
:server_max_requests => nil
|
89
|
+
}.freeze
|
90
|
+
|
91
|
+
def initialize(client_class, servers, options = {})
|
92
|
+
super
|
93
|
+
@options = RETRYING_DEFAULTS.merge(@options)
|
94
|
+
@retries = options[:retries] || @server_list.size
|
95
|
+
@request_count = 0
|
96
|
+
@max_requests = @options[:server_max_requests]
|
97
|
+
@retry_period = @options[:server_retry_period]
|
98
|
+
rebuild_live_server_list!
|
99
|
+
end
|
100
|
+
|
101
|
+
def connect!
|
102
|
+
@current_server = next_server
|
103
|
+
super
|
104
|
+
rescue Thrift::TransportException, Errno::ECONNREFUSED
|
105
|
+
retry
|
106
|
+
end
|
107
|
+
|
108
|
+
def disconnect!
|
109
|
+
# Keep live servers in the list if we have a retry period. Otherwise,
|
110
|
+
# always eject, because we will always re-add them.
|
111
|
+
if @retry_period && @current_server
|
112
|
+
@live_server_list.unshift(@current_server)
|
113
|
+
end
|
114
|
+
|
115
|
+
super()
|
116
|
+
@request_count = 0
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def next_server
|
122
|
+
if @retry_period
|
123
|
+
rebuild_live_server_list! if Time.now > @last_rebuild + @retry_period
|
124
|
+
raise ThriftClient::NoServersAvailable, "No live servers in #{@server_list.inspect} since #{@last_rebuild.inspect}." if @live_server_list.empty?
|
125
|
+
elsif @live_server_list.empty?
|
126
|
+
rebuild_live_server_list!
|
127
|
+
end
|
128
|
+
@live_server_list.pop
|
129
|
+
end
|
130
|
+
|
131
|
+
def rebuild_live_server_list!
|
132
|
+
@last_rebuild = Time.now
|
133
|
+
if @options[:randomize_server_list]
|
134
|
+
@live_server_list = @server_list.sort_by { rand }
|
135
|
+
else
|
136
|
+
@live_server_list = @server_list.dup
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def handled_proxy(method_name, *args)
|
141
|
+
disconnect_on_max! if @max_requests and @request_count >= @max_requests
|
142
|
+
super
|
143
|
+
end
|
144
|
+
|
145
|
+
def proxy(method_name, *args)
|
146
|
+
super
|
147
|
+
rescue *@options[:exception_classes] => e
|
148
|
+
disconnect_on_error!
|
149
|
+
tries ||= @retries
|
150
|
+
tries -= 1
|
151
|
+
tries == 0 ? handle_exception(e, method_name, args) : retry
|
152
|
+
end
|
153
|
+
|
154
|
+
def send_rpc(method_name, *args)
|
155
|
+
@request_count += 1
|
156
|
+
super
|
157
|
+
end
|
158
|
+
|
159
|
+
def disconnect_on_max!
|
160
|
+
@live_server_list.push(@current_server)
|
161
|
+
disconnect_on_error!
|
162
|
+
end
|
163
|
+
|
164
|
+
def disconnect_on_error!
|
165
|
+
super
|
166
|
+
@request_count = 0
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
module TimingOutThriftClient
|
172
|
+
TIMINGOUT_DEFAULTS = {
|
173
|
+
:timeout => 1,
|
174
|
+
:timeout_overrides => {}
|
175
|
+
}.freeze
|
176
|
+
|
177
|
+
def initialize(client_class, servers, options = {})
|
178
|
+
super
|
179
|
+
@options = TIMINGOUT_DEFAULTS.merge(@options)
|
180
|
+
end
|
181
|
+
|
182
|
+
def connect!
|
183
|
+
super
|
184
|
+
set_method_timeouts!
|
185
|
+
end
|
186
|
+
|
187
|
+
private
|
188
|
+
def set_method_timeouts!
|
189
|
+
return unless has_timeouts?
|
190
|
+
@client_methods.each do |method_name|
|
191
|
+
@client.timeout = @options[:timeout_overrides][method_name.to_sym] || @options[:timeout]
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def has_timeouts?
|
196
|
+
@has_timeouts ||= has_timeouts!
|
197
|
+
end
|
198
|
+
|
199
|
+
def has_timeouts!
|
200
|
+
@options[:timeout_overrides].any? && transport_can_timeout?
|
201
|
+
end
|
202
|
+
|
203
|
+
def transport_can_timeout?
|
204
|
+
if (@options[:transport_wrapper] || @options[:transport]).method_defined?(:timeout=)
|
205
|
+
true
|
206
|
+
else
|
207
|
+
warn "ThriftClient: Timeout overrides have no effect with with transport type #{(@options[:transport_wrapper] || @options[:transport])}"
|
208
|
+
false
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
@@ -2,12 +2,11 @@ module Connection
|
|
2
2
|
class Base
|
3
3
|
attr_accessor :transport, :server
|
4
4
|
|
5
|
-
def initialize(transport, transport_wrapper, server, timeout
|
5
|
+
def initialize(transport, transport_wrapper, server, timeout)
|
6
6
|
@transport = transport
|
7
7
|
@transport_wrapper = transport_wrapper
|
8
8
|
@server = server
|
9
9
|
@timeout = timeout
|
10
|
-
@error_type = error_hash[:handles_error]
|
11
10
|
end
|
12
11
|
|
13
12
|
def connect!
|
@@ -17,4 +16,4 @@ module Connection
|
|
17
16
|
def close
|
18
17
|
end
|
19
18
|
end
|
20
|
-
end
|
19
|
+
end
|
@@ -2,10 +2,10 @@ module Connection
|
|
2
2
|
class Factory
|
3
3
|
def self.create(transport, transport_wrapper, server, timeout)
|
4
4
|
if transport == Thrift::HTTPClientTransport
|
5
|
-
Connection::HTTP.new(transport, transport_wrapper, server, timeout
|
5
|
+
Connection::HTTP.new(transport, transport_wrapper, server, timeout)
|
6
6
|
else
|
7
|
-
Connection::Socket.new(transport, transport_wrapper, server, timeout
|
7
|
+
Connection::Socket.new(transport, transport_wrapper, server, timeout)
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
11
|
-
end
|
11
|
+
end
|
@@ -17,7 +17,16 @@ module Thrift
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def open
|
20
|
+
fiber = Fiber.current
|
20
21
|
@connection = EventMachineConnection.connect(@host, @port, @timeout)
|
22
|
+
@connection.callback do
|
23
|
+
fiber.resume
|
24
|
+
end
|
25
|
+
@connection.errback do
|
26
|
+
fiber.resume
|
27
|
+
end
|
28
|
+
Fiber.yield
|
29
|
+
@connection
|
21
30
|
end
|
22
31
|
|
23
32
|
def close
|
@@ -56,7 +65,6 @@ module Thrift
|
|
56
65
|
def initialize(host, port=9090)
|
57
66
|
@host, @port = host, port
|
58
67
|
@index = 0
|
59
|
-
@reconnecting = false
|
60
68
|
@connected = false
|
61
69
|
@buf = ''
|
62
70
|
end
|
@@ -69,6 +77,7 @@ module Thrift
|
|
69
77
|
end
|
70
78
|
|
71
79
|
def blocking_read(size)
|
80
|
+
raise IOError, "lost connection to #{@host}:#{@port}" unless @connected
|
72
81
|
trap do
|
73
82
|
if can_read?(size)
|
74
83
|
yank(size)
|
@@ -103,20 +112,15 @@ module Thrift
|
|
103
112
|
end
|
104
113
|
|
105
114
|
def connection_completed
|
106
|
-
@reconnecting = false
|
107
115
|
@connected = true
|
108
116
|
succeed
|
109
117
|
end
|
110
118
|
|
111
119
|
def unbind
|
112
|
-
|
113
|
-
if @connected or !@reconnecting
|
114
|
-
EM.add_timer(1) {
|
115
|
-
# XXX Connect timeout?
|
116
|
-
reconnect @host, @port
|
117
|
-
}
|
120
|
+
if @connected
|
118
121
|
@connected = false
|
119
|
-
|
122
|
+
else
|
123
|
+
fail
|
120
124
|
end
|
121
125
|
end
|
122
126
|
|
data/lib/thrift_client.rb
CHANGED
@@ -10,34 +10,14 @@ end
|
|
10
10
|
require 'rubygems'
|
11
11
|
require 'thrift_client/thrift'
|
12
12
|
require 'thrift_client/connection'
|
13
|
+
require 'thrift_client/abstract_thrift_client'
|
13
14
|
|
14
|
-
class ThriftClient
|
15
|
-
|
15
|
+
class ThriftClient < AbstractThriftClient
|
16
|
+
# This error is for backwards compatibility only. If defined in
|
17
|
+
# RetryingThriftClient instead, causes the test suite will break.
|
16
18
|
class NoServersAvailable < StandardError; end
|
17
|
-
|
18
|
-
|
19
|
-
:protocol => Thrift::BinaryProtocol,
|
20
|
-
:protocol_extra_params => [],
|
21
|
-
:transport => Thrift::Socket,
|
22
|
-
:transport_wrapper => Thrift::FramedTransport,
|
23
|
-
:randomize_server_list => true,
|
24
|
-
:exception_classes => [
|
25
|
-
IOError,
|
26
|
-
Thrift::Exception,
|
27
|
-
Thrift::ProtocolException,
|
28
|
-
Thrift::ApplicationException,
|
29
|
-
Thrift::TransportException,
|
30
|
-
NoServersAvailable],
|
31
|
-
:raise => true,
|
32
|
-
:retries => nil,
|
33
|
-
:server_retry_period => 1,
|
34
|
-
:server_max_requests => nil,
|
35
|
-
:timeout => 1,
|
36
|
-
:timeout_overrides => {},
|
37
|
-
:defaults => {}
|
38
|
-
}.freeze
|
39
|
-
|
40
|
-
attr_reader :client, :client_class, :current_server, :server_list, :options
|
19
|
+
include RetryingThriftClient
|
20
|
+
include TimingOutThriftClient
|
41
21
|
|
42
22
|
=begin rdoc
|
43
23
|
Create a new ThriftClient instance. Accepts an internal Thrift client class (such as CassandraRb::Client), a list of servers with ports, and optional parameters.
|
@@ -48,6 +28,7 @@ Valid optional parameters are:
|
|
48
28
|
<tt>:protocol_extra_params</tt>:: An array of additional parameters to pass to the protocol initialization call. Defaults to <tt>[]</tt>.
|
49
29
|
<tt>:transport</tt>:: Which Thrift transport to use. Defaults to <tt>Thrift::FramedTransport</tt>.
|
50
30
|
<tt>:randomize_server_list</tt>:: Whether to connect to the servers randomly, instead of in order. Defaults to <tt>true</tt>.
|
31
|
+
<tt>:exception_classes</tt>:: Which exceptions to catch and retry when sending a request. Defaults to <tt>[IOError, Thrift::Exception, Thrift::ProtocolException, Thrift::ApplicationException, Thrift::TransportException, NoServersAvailable]</tt>
|
51
32
|
<tt>:raise</tt>:: Whether to reraise errors if no responsive servers are found. Defaults to <tt>true</tt>.
|
52
33
|
<tt>:retries</tt>:: How many times to retry a request. Defaults to the number of servers defined.
|
53
34
|
<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.
|
@@ -59,100 +40,6 @@ Valid optional parameters are:
|
|
59
40
|
=end rdoc
|
60
41
|
|
61
42
|
def initialize(client_class, servers, options = {})
|
62
|
-
|
63
|
-
@client_class = client_class
|
64
|
-
@server_list = Array(servers)
|
65
|
-
@retries = options[:retries] || @server_list.size
|
66
|
-
|
67
|
-
if @options[:timeout_overrides].any?
|
68
|
-
if (@options[:transport_wrapper] || @options[:transport]).method_defined?(:timeout=)
|
69
|
-
@set_timeout = true
|
70
|
-
else
|
71
|
-
warn "ThriftClient: Timeout overrides have no effect with with transport type #{(@options[:transport_wrapper] || @options[:transport])}"
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
@request_count = 0
|
76
|
-
@max_requests = @options[:server_max_requests]
|
77
|
-
@retry_period = @options[:server_retry_period]
|
78
|
-
rebuild_live_server_list!
|
79
|
-
|
80
|
-
@client_class.instance_methods.each do |method_name|
|
81
|
-
if method_name =~ /^recv_(.*)$/
|
82
|
-
instance_eval("def #{$1}(*args); proxy(:'#{$1}', *args); end")
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
# Force the client to connect to the server.
|
88
|
-
def connect!
|
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
|
94
|
-
@transport.close rescue nil
|
95
|
-
retry
|
96
|
-
end
|
97
|
-
|
98
|
-
# Force the client to disconnect from the server.
|
99
|
-
def disconnect!(keep = true)
|
100
|
-
@connection.close rescue nil
|
101
|
-
|
102
|
-
# Keep live servers in the list if we have a retry period. Otherwise,
|
103
|
-
# always eject, because we will always re-add them.
|
104
|
-
if keep and @retry_period and @current_server
|
105
|
-
@live_server_list.unshift(@current_server)
|
106
|
-
end
|
107
|
-
|
108
|
-
@request_count = 0
|
109
|
-
@client = nil
|
110
|
-
@current_server = nil
|
111
|
-
end
|
112
|
-
|
113
|
-
private
|
114
|
-
|
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
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
def proxy(method_name, *args)
|
135
|
-
disconnect! if @max_requests and @request_count >= @max_requests
|
136
|
-
connect! unless @client
|
137
|
-
|
138
|
-
set_timeout!(method_name) if @set_timeout
|
139
|
-
@request_count += 1
|
140
|
-
@client.send(method_name, *args)
|
141
|
-
rescue NoServersAvailable => e
|
142
|
-
handle_exception(e, method_name, args)
|
143
|
-
rescue *@options[:exception_classes] => e
|
144
|
-
disconnect!(false)
|
145
|
-
tries ||= @retries
|
146
|
-
tries -= 1
|
147
|
-
tries == 0 ? handle_exception(e, method_name, args) : retry
|
148
|
-
end
|
149
|
-
|
150
|
-
def set_timeout!(method_name)
|
151
|
-
@client.timeout = @options[:timeout_overrides][method_name.to_sym] || @options[:timeout]
|
152
|
-
end
|
153
|
-
|
154
|
-
def handle_exception(e, method_name, args=nil)
|
155
|
-
raise e if @options[:raise]
|
156
|
-
@options[:defaults][method_name.to_sym]
|
43
|
+
super
|
157
44
|
end
|
158
45
|
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/test_helper"
|
2
|
+
|
3
|
+
class MultipleWorkingServersTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@servers = ["127.0.0.1:1461", "127.0.0.1:1462", "127.0.0.1:1463"]
|
6
|
+
@socket = 1461
|
7
|
+
@timeout = 0.2
|
8
|
+
@options = {:protocol_extra_params => [false]}
|
9
|
+
@pids = []
|
10
|
+
@servers.each do |s|
|
11
|
+
@pids << Process.fork do
|
12
|
+
Signal.trap("INT") { exit }
|
13
|
+
Greeter::Server.new(s.split(':').last).serve
|
14
|
+
end
|
15
|
+
end
|
16
|
+
# Need to give the child process a moment to open the listening socket or
|
17
|
+
# we get occasional "could not connect" errors in tests.
|
18
|
+
sleep 0.05
|
19
|
+
end
|
20
|
+
|
21
|
+
def teardown
|
22
|
+
@pids.each do |pid|
|
23
|
+
Process.kill("INT", pid)
|
24
|
+
Process.wait(pid)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_server_creates_new_client_that_can_talk_to_all_servers_after_disconnect
|
29
|
+
client = ThriftClient.new(Greeter::Client, @servers, @options)
|
30
|
+
client.greeting("someone")
|
31
|
+
internal_client = client.client
|
32
|
+
client.greeting("someone")
|
33
|
+
assert_equal internal_client, client.client # Sanity check
|
34
|
+
|
35
|
+
client.disconnect!
|
36
|
+
client.greeting("someone")
|
37
|
+
internal_client = client.client
|
38
|
+
client.greeting("someone")
|
39
|
+
assert_equal internal_client, client.client
|
40
|
+
internal_client = client.client
|
41
|
+
client.greeting("someone")
|
42
|
+
assert_equal internal_client, client.client
|
43
|
+
|
44
|
+
# Moves on to the second server
|
45
|
+
assert_nothing_raised {
|
46
|
+
client.greeting("someone")
|
47
|
+
client.greeting("someone")
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_server_doesnt_max_out_after_explicit_disconnect
|
52
|
+
client = ThriftClient.new(Greeter::Client, @servers, @options.merge(:server_max_requests => 2))
|
53
|
+
client.greeting("someone")
|
54
|
+
internal_client = client.client
|
55
|
+
client.greeting("someone")
|
56
|
+
assert_equal internal_client, client.client # Sanity check
|
57
|
+
|
58
|
+
client.disconnect!
|
59
|
+
|
60
|
+
client.greeting("someone")
|
61
|
+
internal_client = client.client
|
62
|
+
client.greeting("someone")
|
63
|
+
assert_equal internal_client, client.client, "ThriftClient should not have reset the internal client if the counter was reset on disconnect"
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_server_disconnect_doesnt_drop_servers_with_retry_period
|
67
|
+
client = ThriftClient.new(Greeter::Client, @servers, @options.merge(:server_max_requests => 2, :retry_period => 1))
|
68
|
+
3.times {
|
69
|
+
client.greeting("someone")
|
70
|
+
internal_client = client.client
|
71
|
+
client.greeting("someone")
|
72
|
+
assert_equal internal_client, client.client # Sanity check
|
73
|
+
|
74
|
+
client.disconnect!
|
75
|
+
|
76
|
+
client.greeting("someone")
|
77
|
+
internal_client = client.client
|
78
|
+
client.greeting("someone")
|
79
|
+
assert_equal internal_client, client.client, "ThriftClient should not have reset the internal client if the counter was reset on disconnect"
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
def test_server_max_requests
|
85
|
+
client = ThriftClient.new(Greeter::Client, @servers, @options.merge(:server_max_requests => 2))
|
86
|
+
|
87
|
+
client.greeting("someone")
|
88
|
+
internal_client = client.client
|
89
|
+
|
90
|
+
client.greeting("someone")
|
91
|
+
assert_equal internal_client, client.client
|
92
|
+
|
93
|
+
# This next call maxes out the requests for that "client" object
|
94
|
+
# and moves on to the next.
|
95
|
+
client.greeting("someone")
|
96
|
+
assert_not_equal internal_client, new_client = client.client
|
97
|
+
|
98
|
+
# And here we should still have the same client as the last one...
|
99
|
+
client.greeting("someone")
|
100
|
+
assert_equal new_client, client.client
|
101
|
+
|
102
|
+
# Until we max it out, too.
|
103
|
+
client.greeting("someone")
|
104
|
+
assert_not_equal new_client, client.client
|
105
|
+
assert_not_nil client.client
|
106
|
+
|
107
|
+
new_new_client = client.client
|
108
|
+
# And we should still have one server left
|
109
|
+
client.greeting("someone")
|
110
|
+
assert_equal new_new_client, client.client
|
111
|
+
end
|
112
|
+
end
|
data/test/thrift_client_test.rb
CHANGED
@@ -121,13 +121,31 @@ class ThriftClientTest < Test::Unit::TestCase
|
|
121
121
|
assert_raises(ThriftClient::NoServersAvailable) { client.greeting("someone") }
|
122
122
|
end
|
123
123
|
|
124
|
-
def
|
124
|
+
def test_client_with_retry_period_drops_servers
|
125
|
+
client = ThriftClient.new(Greeter::Client, @servers[0,2], @options.merge(:server_retry_period => 1))
|
126
|
+
assert_raises(ThriftClient::NoServersAvailable) { client.greeting("someone") }
|
127
|
+
sleep 1.1
|
128
|
+
assert_raises(ThriftClient::NoServersAvailable) { client.greeting("someone") }
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_server_max_requests_with_downed_servers
|
125
132
|
client = ThriftClient.new(Greeter::Client, @servers, @options.merge(:server_max_requests => 2))
|
126
133
|
client.greeting("someone")
|
127
134
|
internal_client = client.client
|
128
135
|
client.greeting("someone")
|
129
136
|
assert_equal internal_client, client.client
|
130
|
-
|
137
|
+
|
138
|
+
# This next call maxes out the requests for that "client" object
|
139
|
+
# and moves on to the next.
|
140
|
+
client.greeting("someone")
|
141
|
+
assert_not_equal internal_client, new_client = client.client
|
142
|
+
|
143
|
+
# And here we should still have the same client as the last one...
|
144
|
+
client.greeting("someone")
|
145
|
+
assert_equal new_client, client.client
|
146
|
+
|
147
|
+
# Until we max it out, too.
|
148
|
+
client.greeting("someone")
|
131
149
|
assert_not_equal internal_client, client.client
|
132
150
|
end
|
133
151
|
|
@@ -140,4 +158,4 @@ class ThriftClientTest < Test::Unit::TestCase
|
|
140
158
|
ensure
|
141
159
|
socket.close
|
142
160
|
end
|
143
|
-
end
|
161
|
+
end
|
data/thrift_client.gemspec
CHANGED
@@ -2,24 +2,22 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{thrift_client}
|
5
|
-
s.version = "0.4.
|
5
|
+
s.version = "0.4.1"
|
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.
|
10
|
-
s.date = %q{2010-02-18}
|
9
|
+
s.date = %q{2010-03-30}
|
11
10
|
s.description = %q{A Thrift client wrapper that encapsulates some common failover behavior.}
|
12
11
|
s.email = %q{}
|
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"]
|
12
|
+
s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.rdoc", "lib/thrift_client.rb", "lib/thrift_client/abstract_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"]
|
13
|
+
s.files = ["CHANGELOG", "LICENSE", "Manifest", "README.rdoc", "Rakefile", "lib/thrift_client.rb", "lib/thrift_client/abstract_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/multiple_working_servers_test.rb", "test/simple_test.rb", "test/test_helper.rb", "test/thrift_client_http_test.rb", "test/thrift_client_test.rb", "thrift_client.gemspec"]
|
15
14
|
s.homepage = %q{http://blog.evanweaver.com/files/doc/fauna/thrift_client/}
|
16
15
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Thrift_client", "--main", "README.rdoc"]
|
17
16
|
s.require_paths = ["lib"]
|
18
17
|
s.rubyforge_project = %q{fauna}
|
19
|
-
s.rubygems_version = %q{1.3.
|
20
|
-
s.signing_key = %q{/Users/ryan/.gemkeys/gem-private_key.pem}
|
18
|
+
s.rubygems_version = %q{1.3.6}
|
21
19
|
s.summary = %q{A Thrift client wrapper that encapsulates some common failover behavior.}
|
22
|
-
s.test_files = ["test/simple_test.rb", "test/test_helper.rb", "test/thrift_client_http_test.rb", "test/thrift_client_test.rb"]
|
20
|
+
s.test_files = ["test/multiple_working_servers_test.rb", "test/simple_test.rb", "test/test_helper.rb", "test/thrift_client_http_test.rb", "test/thrift_client_test.rb"]
|
23
21
|
|
24
22
|
if s.respond_to? :specification_version then
|
25
23
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
metadata
CHANGED
@@ -1,48 +1,34 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thrift_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 4
|
8
|
+
- 1
|
9
|
+
version: 0.4.1
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Evan Weaver
|
8
13
|
autorequire:
|
9
14
|
bindir: bin
|
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-----
|
15
|
+
cert_chain: []
|
32
16
|
|
33
|
-
date: 2010-
|
17
|
+
date: 2010-03-30 00:00:00 -07:00
|
34
18
|
default_executable:
|
35
19
|
dependencies:
|
36
20
|
- !ruby/object:Gem::Dependency
|
37
21
|
name: thrift
|
38
|
-
|
39
|
-
|
40
|
-
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
41
24
|
requirements:
|
42
25
|
- - ">="
|
43
26
|
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
44
29
|
version: "0"
|
45
|
-
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
46
32
|
description: A Thrift client wrapper that encapsulates some common failover behavior.
|
47
33
|
email: ""
|
48
34
|
executables: []
|
@@ -54,6 +40,7 @@ extra_rdoc_files:
|
|
54
40
|
- LICENSE
|
55
41
|
- README.rdoc
|
56
42
|
- lib/thrift_client.rb
|
43
|
+
- lib/thrift_client/abstract_thrift_client.rb
|
57
44
|
- lib/thrift_client/connection.rb
|
58
45
|
- lib/thrift_client/connection/base.rb
|
59
46
|
- lib/thrift_client/connection/factory.rb
|
@@ -69,6 +56,7 @@ files:
|
|
69
56
|
- README.rdoc
|
70
57
|
- Rakefile
|
71
58
|
- lib/thrift_client.rb
|
59
|
+
- lib/thrift_client/abstract_thrift_client.rb
|
72
60
|
- lib/thrift_client/connection.rb
|
73
61
|
- lib/thrift_client/connection/base.rb
|
74
62
|
- lib/thrift_client/connection/factory.rb
|
@@ -80,6 +68,7 @@ files:
|
|
80
68
|
- test/greeter/greeter.rb
|
81
69
|
- test/greeter/greeter.thrift
|
82
70
|
- test/greeter/server.rb
|
71
|
+
- test/multiple_working_servers_test.rb
|
83
72
|
- test/simple_test.rb
|
84
73
|
- test/test_helper.rb
|
85
74
|
- test/thrift_client_http_test.rb
|
@@ -103,22 +92,26 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
103
92
|
requirements:
|
104
93
|
- - ">="
|
105
94
|
- !ruby/object:Gem::Version
|
95
|
+
segments:
|
96
|
+
- 0
|
106
97
|
version: "0"
|
107
|
-
version:
|
108
98
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
99
|
requirements:
|
110
100
|
- - ">="
|
111
101
|
- !ruby/object:Gem::Version
|
102
|
+
segments:
|
103
|
+
- 0
|
104
|
+
- 8
|
112
105
|
version: "0.8"
|
113
|
-
version:
|
114
106
|
requirements: []
|
115
107
|
|
116
108
|
rubyforge_project: fauna
|
117
|
-
rubygems_version: 1.3.
|
109
|
+
rubygems_version: 1.3.6
|
118
110
|
signing_key:
|
119
111
|
specification_version: 3
|
120
112
|
summary: A Thrift client wrapper that encapsulates some common failover behavior.
|
121
113
|
test_files:
|
114
|
+
- test/multiple_working_servers_test.rb
|
122
115
|
- test/simple_test.rb
|
123
116
|
- test/test_helper.rb
|
124
117
|
- test/thrift_client_http_test.rb
|
data.tar.gz.sig
DELETED
Binary file
|
metadata.gz.sig
DELETED