thrift_client 0.3 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/CHANGELOG +2 -0
- data/lib/thrift_client.rb +44 -19
- data/test/thrift_client_test.rb +23 -19
- data/thrift_client.gemspec +1 -1
- metadata +1 -1
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG
CHANGED
data/lib/thrift_client.rb
CHANGED
@@ -30,12 +30,13 @@ class ThriftClient
|
|
30
30
|
:raise => true,
|
31
31
|
:retries => nil,
|
32
32
|
:server_retry_period => 1,
|
33
|
+
:server_max_requests => nil,
|
33
34
|
:timeout => 1,
|
34
35
|
:timeout_overrides => {},
|
35
36
|
:defaults => {}
|
36
37
|
}.freeze
|
37
38
|
|
38
|
-
attr_reader :client, :client_class, :server_list, :options
|
39
|
+
attr_reader :client, :client_class, :current_server, :server_list, :options
|
39
40
|
|
40
41
|
=begin rdoc
|
41
42
|
Create a new ThriftClient instance. Accepts an internal Thrift client class (such as CassandraRb::Client), a list of servers with ports, and optional parameters.
|
@@ -49,8 +50,9 @@ Valid optional parameters are:
|
|
49
50
|
<tt>:raise</tt>:: Whether to reraise errors if no responsive servers are found. Defaults to <tt>true</tt>.
|
50
51
|
<tt>:retries</tt>:: How many times to retry a request. Defaults to the number of servers defined.
|
51
52
|
<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.
|
52
|
-
<tt>:
|
53
|
-
<tt>:
|
53
|
+
<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).
|
54
|
+
<tt>:timeout</tt>:: Specify the default timeout in seconds. Defaults to <tt>1</tt>.
|
55
|
+
<tt>:timeout_overrides</tt>:: Specify additional timeouts on a per-method basis, in seconds. Only works with <tt>Thrift::BufferedTransport</tt>.
|
54
56
|
<tt>:defaults</tt>:: Specify default values to return on a per-method basis, if <tt>:raise</tt> is set to false.
|
55
57
|
|
56
58
|
=end rdoc
|
@@ -60,7 +62,6 @@ Valid optional parameters are:
|
|
60
62
|
@client_class = client_class
|
61
63
|
@server_list = Array(servers)
|
62
64
|
@retries = options[:retries] || @server_list.size
|
63
|
-
@server_list = @server_list.sort_by { rand } if @options[:randomize_server_list]
|
64
65
|
|
65
66
|
if @options[:timeout_overrides].any?
|
66
67
|
if @options[:transport].instance_methods.include?("timeout=")
|
@@ -69,9 +70,11 @@ Valid optional parameters are:
|
|
69
70
|
warn "ThriftClient: Timeout overrides have no effect with with transport type #{@options[:transport]}"
|
70
71
|
end
|
71
72
|
end
|
72
|
-
|
73
|
-
@
|
74
|
-
@
|
73
|
+
|
74
|
+
@request_count = 0
|
75
|
+
@max_requests = @options[:server_max_requests]
|
76
|
+
@retry_period = @options[:server_retry_period]
|
77
|
+
rebuild_live_server_list!
|
75
78
|
|
76
79
|
@client_class.instance_methods.each do |method_name|
|
77
80
|
if method_name =~ /^recv_(.*)$/
|
@@ -82,37 +85,51 @@ Valid optional parameters are:
|
|
82
85
|
|
83
86
|
# Force the client to connect to the server.
|
84
87
|
def connect!
|
85
|
-
server = next_server
|
86
|
-
|
88
|
+
server = next_server
|
89
|
+
host, port = server.to_s.split(":")
|
90
|
+
raise ArgumentError, 'Servers must be in the form "host:port"' unless host and port
|
87
91
|
|
88
92
|
@transport = @options[:transport].new(
|
89
|
-
Thrift::Socket.new(
|
93
|
+
Thrift::Socket.new(host, port.to_i, @options[:timeout]))
|
90
94
|
@transport.open
|
95
|
+
@current_server = server
|
91
96
|
@client = @client_class.new(@options[:protocol].new(@transport, *@options[:protocol_extra_params]))
|
92
97
|
rescue Thrift::TransportException
|
93
98
|
retry
|
94
99
|
end
|
95
100
|
|
96
101
|
# Force the client to disconnect from the server.
|
97
|
-
def disconnect!
|
102
|
+
def disconnect!(keep = true)
|
98
103
|
@transport.close rescue nil
|
104
|
+
|
105
|
+
# Keep live servers in the list if we have a retry period. Otherwise,
|
106
|
+
# always eject, because we will always re-add them.
|
107
|
+
if keep and @retry_period and @current_server
|
108
|
+
@live_server_list.unshift(@current_server)
|
109
|
+
end
|
110
|
+
|
111
|
+
@request_count = 0
|
99
112
|
@client = nil
|
113
|
+
@current_server = nil
|
100
114
|
end
|
101
115
|
|
102
116
|
private
|
103
117
|
|
104
118
|
def proxy(method_name, *args)
|
119
|
+
disconnect! if @max_requests and @request_count >= @max_requests
|
105
120
|
connect! unless @client
|
121
|
+
|
106
122
|
set_timeout!(method_name) if @set_timeout
|
123
|
+
@request_count += 1
|
107
124
|
@client.send(method_name, *args)
|
108
125
|
rescue NoServersAvailable => e
|
109
126
|
handle_exception(e, method_name, args)
|
110
127
|
rescue *@options[:exception_classes] => e
|
111
|
-
tries ||= @retries
|
128
|
+
tries ||= @retries
|
112
129
|
if (tries -= 1) == 0
|
113
130
|
handle_exception(e, method_name, args)
|
114
131
|
else
|
115
|
-
disconnect!
|
132
|
+
disconnect!(false)
|
116
133
|
retry
|
117
134
|
end
|
118
135
|
end
|
@@ -127,13 +144,21 @@ Valid optional parameters are:
|
|
127
144
|
end
|
128
145
|
|
129
146
|
def next_server
|
130
|
-
if @
|
131
|
-
if
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
@live_server_list = @server_list.dup
|
147
|
+
if @retry_period
|
148
|
+
rebuild_live_server_list! if Time.now > @last_rebuild + @retry_period
|
149
|
+
raise NoServersAvailable, "No live servers in #{@server_list.inspect} since #{@last_rebuild.inspect}." if @live_server_list.empty?
|
150
|
+
elsif @live_server_list.empty?
|
151
|
+
rebuild_live_server_list!
|
136
152
|
end
|
137
153
|
@live_server_list.pop
|
138
154
|
end
|
155
|
+
|
156
|
+
def rebuild_live_server_list!
|
157
|
+
@last_rebuild = Time.now
|
158
|
+
if @options[:randomize_server_list]
|
159
|
+
@live_server_list = @server_list.sort_by { rand }
|
160
|
+
else
|
161
|
+
@live_server_list = @server_list.dup
|
162
|
+
end
|
163
|
+
end
|
139
164
|
end
|
data/test/thrift_client_test.rb
CHANGED
@@ -26,23 +26,17 @@ class ThriftClientTest < Test::Unit::TestCase
|
|
26
26
|
ThriftClient.new(ScribeThrift::Client, @servers.first, @options.merge(:raise => false)).Log(@entry)
|
27
27
|
end
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
def test_dont_raise_with_defaults
|
31
31
|
client = ThriftClient.new(ScribeThrift::Client, @servers.first, @options.merge(:raise => false, :defaults => {:Log => 1}))
|
32
32
|
assert_equal 1, client.Log(@entry)
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
def test_defaults_dont_override_no_method_error
|
36
36
|
client = ThriftClient.new(ScribeThrift::Client, @servers, @options.merge(:raise => false, :defaults => {:Missing => 2}))
|
37
|
-
assert_raises(NoMethodError) { client.Missing(@entry) }
|
37
|
+
assert_raises(NoMethodError) { client.Missing(@entry) }
|
38
38
|
end
|
39
39
|
|
40
|
-
def test_random_server_list
|
41
|
-
@lists = []
|
42
|
-
@lists << ThriftClient.new(ScribeThrift::Client, @servers, @options).server_list while @lists.size < 10
|
43
|
-
assert @lists.uniq.size > 1
|
44
|
-
end
|
45
|
-
|
46
40
|
def test_random_fall_through
|
47
41
|
assert_nothing_raised do
|
48
42
|
10.times { ThriftClient.new(ScribeThrift::Client, @servers, @options).Log(@entry) }
|
@@ -62,35 +56,35 @@ class ThriftClientTest < Test::Unit::TestCase
|
|
62
56
|
client.disconnect!
|
63
57
|
end
|
64
58
|
end
|
65
|
-
|
59
|
+
|
66
60
|
def test_framed_transport_timeout
|
67
61
|
stub_server(@socket) do |socket|
|
68
62
|
measurement = Benchmark.measure do
|
69
63
|
assert_raises(Thrift::TransportException) do
|
70
|
-
ThriftClient.new(ScribeThrift::Client, "127.0.0.1:#{@socket}",
|
64
|
+
ThriftClient.new(ScribeThrift::Client, "127.0.0.1:#{@socket}",
|
71
65
|
@options.merge(:timeout => @timeout)
|
72
|
-
).Log(@entry)
|
66
|
+
).Log(@entry)
|
73
67
|
end
|
74
68
|
end
|
75
69
|
assert((measurement.real > @timeout - 0.01), "#{measurement.real} < #{@timeout}")
|
76
70
|
assert((measurement.real < @timeout + 0.01), "#{measurement.real} > #{@timeout}")
|
77
71
|
end
|
78
72
|
end
|
79
|
-
|
73
|
+
|
80
74
|
def test_buffered_transport_timeout
|
81
75
|
stub_server(@socket) do |socket|
|
82
76
|
measurement = Benchmark.measure do
|
83
77
|
assert_raises(Thrift::TransportException) do
|
84
78
|
ThriftClient.new(ScribeThrift::Client, "127.0.0.1:#{@socket}",
|
85
79
|
@options.merge(:timeout => @timeout, :transport => Thrift::BufferedTransport)
|
86
|
-
).Log(@entry)
|
80
|
+
).Log(@entry)
|
87
81
|
end
|
88
82
|
end
|
89
83
|
assert((measurement.real > @timeout - 0.01), "#{measurement.real} < #{@timeout}")
|
90
84
|
assert((measurement.real < @timeout + 0.01), "#{measurement.real} > #{@timeout}")
|
91
85
|
end
|
92
|
-
end
|
93
|
-
|
86
|
+
end
|
87
|
+
|
94
88
|
def test_buffered_transport_timeout_override
|
95
89
|
# FIXME Large timeout values always are applied twice for some bizarre reason
|
96
90
|
log_timeout = @timeout * 4
|
@@ -99,7 +93,7 @@ class ThriftClientTest < Test::Unit::TestCase
|
|
99
93
|
assert_raises(Thrift::TransportException) do
|
100
94
|
ThriftClient.new(ScribeThrift::Client, "127.0.0.1:#{@socket}",
|
101
95
|
@options.merge(:timeout => @timeout, :timeout_overrides => {:Log => log_timeout}, :transport => Thrift::BufferedTransport)
|
102
|
-
).Log(@entry)
|
96
|
+
).Log(@entry)
|
103
97
|
end
|
104
98
|
end
|
105
99
|
assert((measurement.real > log_timeout - 0.01), "#{measurement.real} < #{log_timeout }")
|
@@ -114,13 +108,23 @@ class ThriftClientTest < Test::Unit::TestCase
|
|
114
108
|
assert_raises(ThriftClient::NoServersAvailable) { client.Log(@entry) }
|
115
109
|
end
|
116
110
|
|
111
|
+
def test_server_max_requests
|
112
|
+
client = ThriftClient.new(ScribeThrift::Client, @servers, @options.merge(:server_max_requests => 2))
|
113
|
+
client.Log(@entry)
|
114
|
+
internal_client = client.client
|
115
|
+
client.Log(@entry)
|
116
|
+
assert_equal internal_client, client.client
|
117
|
+
client.Log(@entry)
|
118
|
+
assert_not_equal internal_client, client.client
|
119
|
+
end
|
120
|
+
|
117
121
|
private
|
118
|
-
|
122
|
+
|
119
123
|
def stub_server(port)
|
120
124
|
socket = TCPServer.new('127.0.0.1', port)
|
121
125
|
Thread.new { socket.accept }
|
122
126
|
yield socket
|
123
127
|
ensure
|
124
128
|
socket.close
|
125
|
-
end
|
129
|
+
end
|
126
130
|
end
|
data/thrift_client.gemspec
CHANGED
metadata
CHANGED
metadata.gz.sig
CHANGED
Binary file
|