thrift_client 0.8.1 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,6 @@
1
+ v0.8.2 Connect errors now mark servers down for _server_retry_period_.
2
+ Added support for cached connections to amortize connection costs.
3
+
1
4
  v0.8.1 Fixed permissions?
2
5
 
3
6
  v0.8.0 Update to thrift 0.8.0
data/Manifest CHANGED
@@ -11,6 +11,7 @@ lib/thrift_client/connection/factory.rb
11
11
  lib/thrift_client/connection/http.rb
12
12
  lib/thrift_client/connection/socket.rb
13
13
  lib/thrift_client/event_machine.rb
14
+ lib/thrift_client/server.rb
14
15
  lib/thrift_client/simple.rb
15
16
  lib/thrift_client/thrift.rb
16
17
  test/greeter/greeter.rb
@@ -1,17 +1,5 @@
1
1
  class AbstractThriftClient
2
-
3
- class Server
4
- attr_reader :connection_string, :marked_down_at
5
-
6
- def initialize(connection_string)
7
- @connection_string = connection_string
8
- end
9
- alias to_s connection_string
10
-
11
- def mark_down!
12
- @marked_down_at = Time.now
13
- end
14
- end
2
+ include ThriftHelpers
15
3
 
16
4
  DISCONNECT_ERRORS = [
17
5
  IOError,
@@ -41,7 +29,8 @@ class AbstractThriftClient
41
29
  :wrapped_exception_classes => DEFAULT_WRAPPED_ERRORS,
42
30
  :connect_timeout => 0.1,
43
31
  :timeout => 1,
44
- :timeout_overrides => {}
32
+ :timeout_overrides => {},
33
+ :cached_connections => false
45
34
  }
46
35
 
47
36
  attr_reader :client, :client_class, :current_server, :server_list, :options, :client_methods
@@ -50,7 +39,9 @@ class AbstractThriftClient
50
39
  @options = DEFAULTS.merge(options)
51
40
  @options[:server_retry_period] ||= 0
52
41
  @client_class = client_class
53
- @server_list = Array(servers).collect{|s| Server.new(s)}.sort_by { rand }
42
+ @server_list = Array(servers).collect do |s|
43
+ Server.new(s, @options[:cached_connections])
44
+ end.sort_by { rand }
54
45
  @current_server = @server_list.first
55
46
 
56
47
  @callbacks = {}
@@ -101,16 +92,23 @@ class AbstractThriftClient
101
92
  # call.
102
93
  def connect!
103
94
  @current_server = next_live_server
104
- @connection = Connection::Factory.create(@options[:transport], @options[:transport_wrapper], @current_server.connection_string, @options[:connect_timeout])
105
- @connection.connect!
106
- transport = @connection.transport
107
- transport.timeout = @options[:timeout] if transport_can_timeout?
108
- @client = @client_class.new(@options[:protocol].new(transport, *@options[:protocol_extra_params]))
95
+ @current_server.open(@options[:transport],
96
+ @options[:transport_wrapper],
97
+ @options[:connect_timeout],
98
+ @options[:timeout])
99
+ @client = @client_class.new(@options[:protocol].new(@current_server, *@options[:protocol_extra_params]))
109
100
  do_callbacks(:post_connect, self)
101
+ rescue IOError, Thrift::TransportException
102
+ disconnect!(true)
103
+ retry
110
104
  end
111
105
 
112
- def disconnect!
113
- @connection.close rescue nil #TODO
106
+ def disconnect!(error = false)
107
+ if @current_server
108
+ @current_server.mark_down!(@options[:server_retry_period]) if error
109
+ @current_server.close
110
+ end
111
+
114
112
  @client = nil
115
113
  @current_server = nil
116
114
  @request_count = 0
@@ -130,16 +128,16 @@ class AbstractThriftClient
130
128
  @server_index ||= 0
131
129
  @server_list.length.times do |i|
132
130
  cur = (1 + @server_index + i) % @server_list.length
133
- if !@server_list[cur].marked_down_at || (@server_list[cur].marked_down_at + @options[:server_retry_period] <= Time.now)
131
+ if @server_list[cur].up?
134
132
  @server_index = cur
135
133
  return @server_list[cur]
136
134
  end
137
135
  end
138
- raise ThriftClient::NoServersAvailable, "No live servers in #{@server_list.inspect} since #{@last_rebuild.inspect}."
136
+ raise ThriftClient::NoServersAvailable, "No live servers in #{@server_list.inspect}."
139
137
  end
140
138
 
141
139
  def handled_proxy(method_name, *args)
142
- disconnect_on_max! if @options[:server_max_requests] && @request_count >= @options[:server_max_requests]
140
+ disconnect! if @options[:server_max_requests] && @request_count >= @options[:server_max_requests]
143
141
  begin
144
142
  connect! unless @client
145
143
  if has_timeouts?
@@ -151,7 +149,7 @@ class AbstractThriftClient
151
149
  rescue *@options[:exception_class_overrides] => e
152
150
  raise_or_default(e, method_name)
153
151
  rescue *@options[:exception_classes] => e
154
- disconnect_on_error!
152
+ disconnect!(true)
155
153
  tries ||= (@options[:retry_overrides][method_name.to_sym] || @options[:retries]) + 1
156
154
  tries -= 1
157
155
  if tries > 0
@@ -181,15 +179,6 @@ class AbstractThriftClient
181
179
  end
182
180
  end
183
181
 
184
- def disconnect_on_max!
185
- disconnect!
186
- end
187
-
188
- def disconnect_on_error!
189
- @current_server.mark_down! if @current_server
190
- disconnect!
191
- end
192
-
193
182
  def has_timeouts?
194
183
  @has_timeouts ||= @options[:timeout_overrides].any? && transport_can_timeout?
195
184
  end
@@ -1,19 +1,25 @@
1
- module Connection
2
- class Base
3
- attr_accessor :transport, :server
1
+ module ThriftHelpers
2
+ module Connection
3
+ class Base
4
+ attr_accessor :transport, :server
4
5
 
5
- def initialize(transport, transport_wrapper, server, timeout)
6
- @transport = transport
7
- @transport_wrapper = transport_wrapper
8
- @server = server
9
- @timeout = timeout
10
- end
6
+ def initialize(transport, transport_wrapper, server, timeout)
7
+ @transport = transport
8
+ @transport_wrapper = transport_wrapper
9
+ @server = server
10
+ @timeout = timeout
11
+ end
11
12
 
12
- def connect!
13
- raise NotImplementedError
14
- end
13
+ def connect!
14
+ raise NotImplementedError
15
+ end
16
+
17
+ def open?
18
+ @transport.open?
19
+ end
15
20
 
16
- def close
21
+ def close
22
+ end
17
23
  end
18
24
  end
19
25
  end
@@ -1,10 +1,12 @@
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)
6
- else
7
- Connection::Socket.new(transport, transport_wrapper, server, timeout)
1
+ module ThriftHelpers
2
+ module Connection
3
+ class Factory
4
+ def self.create(transport, transport_wrapper, server, timeout)
5
+ if transport == Thrift::HTTPClientTransport
6
+ Connection::HTTP.new(transport, transport_wrapper, server, timeout)
7
+ else
8
+ Connection::Socket.new(transport, transport_wrapper, server, timeout)
9
+ end
8
10
  end
9
11
  end
10
12
  end
@@ -1,18 +1,20 @@
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
1
+ module ThriftHelpers
2
+ module Connection
3
+ class HTTP < Base
4
+ def connect!
5
+ uri = parse_server(@server)
6
+ @transport = Thrift::HTTPClientTransport.new(@server)
7
+ http = Net::HTTP.new(uri.host, uri.port)
8
+ http.use_ssl = uri.scheme == "https"
9
+ http.get(uri.path)
10
+ end
10
11
 
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
12
+ private
13
+ def parse_server(server)
14
+ uri = URI.parse(server)
15
+ raise ArgumentError, 'Servers must start with http' unless uri.scheme =~ /^http/
16
+ uri
17
+ end
16
18
  end
17
19
  end
18
- end
20
+ end
@@ -1,22 +1,24 @@
1
- module Connection
2
- class Socket < Base
3
- def close
4
- @transport.close
5
- end
1
+ module ThriftHelpers
2
+ module Connection
3
+ class Socket < Base
4
+ def close
5
+ @transport.close
6
+ end
6
7
 
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
8
+ def connect!
9
+ host, port = parse_server(@server)
10
+ @transport = @transport.new(*[host, port.to_i, @timeout])
11
+ @transport = @transport_wrapper.new(@transport) if @transport_wrapper
12
+ @transport.open
13
+ end
13
14
 
14
- private
15
+ private
15
16
 
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]
17
+ def parse_server(server)
18
+ host, port = server.to_s.split(":")
19
+ raise ArgumentError, 'Servers must be in the form "host:port"' unless host and port
20
+ [host, port]
21
+ end
20
22
  end
21
23
  end
22
24
  end
@@ -0,0 +1,100 @@
1
+ require 'thrift_client/connection'
2
+
3
+ module ThriftHelpers
4
+ class Server
5
+ class ServerMarkedDown < StandardError; end
6
+
7
+ def initialize(connection_string, cached = true)
8
+ @connection_string = connection_string
9
+ @connection = nil
10
+ @cached = cached
11
+ @marked_down_til = nil
12
+ end
13
+
14
+ def mark_down!(til)
15
+ close(true)
16
+ @marked_down_til = Time.now + til
17
+ end
18
+
19
+ def up?
20
+ !down?
21
+ end
22
+
23
+ def down?
24
+ @marked_down_til && @marked_down_til > Time.now
25
+ end
26
+
27
+ def to_s
28
+ @connection_string
29
+ end
30
+
31
+ def open(trans, wrap, conn_timeout, trans_timeout)
32
+ if down?
33
+ raise ServerMarkedDown, "marked down until #{@marked_down_til}"
34
+ end
35
+
36
+ if @connection.nil? || (@cached && !@connection.open?)
37
+ @connection = Connection::Factory.create(trans, wrap, @connection_string, conn_timeout)
38
+ @connection.connect!
39
+ end
40
+
41
+ if wrap || trans.respond_to?(:timeout=)
42
+ timeout = trans_timeout
43
+ end
44
+
45
+ self
46
+ end
47
+
48
+ def open?
49
+ @connection && @connection.open?
50
+ end
51
+
52
+ def close(teardown = false)
53
+ if teardown || !@cached
54
+ @connection.close rescue nil #TODO
55
+ @connection = nil
56
+ end
57
+ end
58
+
59
+ def transport
60
+ return nil unless @connection
61
+ @connection.transport
62
+ end
63
+
64
+ module TransportInterface
65
+ def read(sz)
66
+ transport.read(sz)
67
+ end
68
+
69
+ def read_byte
70
+ transport.read_byte
71
+ end
72
+
73
+ def read_into_buffer(buffer, size)
74
+ transport.read_into_buffer(buffer, size)
75
+ end
76
+
77
+ def read_all(sz)
78
+ transport.read_all(sz)
79
+ end
80
+
81
+ def write(buf)
82
+ transport.write(buf)
83
+ end
84
+ alias_method :<<, :write
85
+
86
+ def flush
87
+ transport.flush
88
+ end
89
+
90
+ def timeout=(timeout)
91
+ transport.timeout = timeout
92
+ end
93
+
94
+ def timeout
95
+ transport.timeout
96
+ end
97
+ end
98
+ include TransportInterface
99
+ end
100
+ end
data/lib/thrift_client.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'thrift'
2
2
  require 'thrift_client/thrift'
3
- require 'thrift_client/connection'
3
+ require 'thrift_client/server'
4
4
  require 'thrift_client/abstract_thrift_client'
5
5
 
6
6
  class ThriftClient < AbstractThriftClient
@@ -48,8 +48,8 @@ class ThriftClientTest < Test::Unit::TestCase
48
48
 
49
49
  # disconnect_on_error! is called every time a server related
50
50
  # connection error happens. it will be called every try (so, retries + 1)
51
- singleton_class.send :define_method, :disconnect_on_error! do |*args|
52
- times_called += 1; super *args
51
+ singleton_class.send :define_method, :disconnect! do |*args|
52
+ times_called += 1 if args[0]; super *args
53
53
  end
54
54
 
55
55
  assert_raises(Greeter::Client::TransportException) { client.greeting("someone") }
@@ -2,22 +2,22 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "thrift_client"
5
- s.version = "0.8.1"
5
+ s.version = "0.8.2"
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, Ryan King, Jeff Hodges"]
9
- s.date = "2012-01-19"
9
+ s.date = "2012-09-11"
10
10
  s.description = "A Thrift client wrapper that encapsulates some common failover behavior."
11
11
  s.email = ""
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"]
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/server.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/server.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"]
14
14
  s.homepage = "http://fauna.github.com/fauna/thrift_client/"
15
15
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Thrift_client", "--main", "README.rdoc"]
16
16
  s.require_paths = ["lib"]
17
17
  s.rubyforge_project = "fauna"
18
- s.rubygems_version = "1.8.15"
18
+ s.rubygems_version = "1.8.23"
19
19
  s.summary = "A Thrift client wrapper that encapsulates some common failover behavior."
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"]
20
+ s.test_files = ["test/thrift_client_http_test.rb", "test/thrift_client_test.rb", "test/test_helper.rb", "test/multiple_working_servers_test.rb", "test/simple_test.rb"]
21
21
 
22
22
  if s.respond_to? :specification_version then
23
23
  s.specification_version = 3
metadata CHANGED
@@ -1,45 +1,37 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: thrift_client
3
- version: !ruby/object:Gem::Version
4
- hash: 61
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.8.2
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 8
9
- - 1
10
- version: 0.8.1
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Evan Weaver, Ryan King, Jeff Hodges
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-01-19 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2012-09-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: thrift
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
18
+ requirements:
26
19
  - - ~>
27
- - !ruby/object:Gem::Version
28
- hash: 63
29
- segments:
30
- - 0
31
- - 8
32
- - 0
20
+ - !ruby/object:Gem::Version
33
21
  version: 0.8.0
34
22
  type: :runtime
35
- version_requirements: *id001
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.8.0
36
30
  description: A Thrift client wrapper that encapsulates some common failover behavior.
37
- email: ""
31
+ email: ''
38
32
  executables: []
39
-
40
33
  extensions: []
41
-
42
- extra_rdoc_files:
34
+ extra_rdoc_files:
43
35
  - CHANGELOG
44
36
  - LICENSE
45
37
  - README.rdoc
@@ -51,9 +43,10 @@ extra_rdoc_files:
51
43
  - lib/thrift_client/connection/http.rb
52
44
  - lib/thrift_client/connection/socket.rb
53
45
  - lib/thrift_client/event_machine.rb
46
+ - lib/thrift_client/server.rb
54
47
  - lib/thrift_client/simple.rb
55
48
  - lib/thrift_client/thrift.rb
56
- files:
49
+ files:
57
50
  - CHANGELOG
58
51
  - LICENSE
59
52
  - Manifest
@@ -67,6 +60,7 @@ files:
67
60
  - lib/thrift_client/connection/http.rb
68
61
  - lib/thrift_client/connection/socket.rb
69
62
  - lib/thrift_client/event_machine.rb
63
+ - lib/thrift_client/server.rb
70
64
  - lib/thrift_client/simple.rb
71
65
  - lib/thrift_client/thrift.rb
72
66
  - test/greeter/greeter.rb
@@ -80,46 +74,37 @@ files:
80
74
  - thrift_client.gemspec
81
75
  homepage: http://fauna.github.com/fauna/thrift_client/
82
76
  licenses: []
83
-
84
77
  post_install_message:
85
- rdoc_options:
78
+ rdoc_options:
86
79
  - --line-numbers
87
80
  - --inline-source
88
81
  - --title
89
82
  - Thrift_client
90
83
  - --main
91
84
  - README.rdoc
92
- require_paths:
85
+ require_paths:
93
86
  - lib
94
- required_ruby_version: !ruby/object:Gem::Requirement
87
+ required_ruby_version: !ruby/object:Gem::Requirement
95
88
  none: false
96
- requirements:
97
- - - ">="
98
- - !ruby/object:Gem::Version
99
- hash: 3
100
- segments:
101
- - 0
102
- version: "0"
103
- required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ! '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
94
  none: false
105
- requirements:
106
- - - ">="
107
- - !ruby/object:Gem::Version
108
- hash: 27
109
- segments:
110
- - 0
111
- - 8
112
- version: "0.8"
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0.8'
113
99
  requirements: []
114
-
115
100
  rubyforge_project: fauna
116
- rubygems_version: 1.8.15
101
+ rubygems_version: 1.8.23
117
102
  signing_key:
118
103
  specification_version: 3
119
104
  summary: A Thrift client wrapper that encapsulates some common failover behavior.
120
- test_files:
121
- - test/multiple_working_servers_test.rb
122
- - test/simple_test.rb
123
- - test/test_helper.rb
105
+ test_files:
124
106
  - test/thrift_client_http_test.rb
125
107
  - test/thrift_client_test.rb
108
+ - test/test_helper.rb
109
+ - test/multiple_working_servers_test.rb
110
+ - test/simple_test.rb