thrift_client 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,4 +1,6 @@
1
1
 
2
+ v0.1.2. Support default responses.
3
+
2
4
  v0.1.1. Support server_retry_period.
3
5
 
4
6
  v0.1. First release.
data/Manifest CHANGED
@@ -4,5 +4,6 @@ Manifest
4
4
  README
5
5
  Rakefile
6
6
  lib/thrift_client.rb
7
+ lib/thrift_client/thrift.rb
7
8
  test/test_helper.rb
8
9
  test/thrift_client_test.rb
data/README CHANGED
@@ -11,11 +11,24 @@ The public certificate for this gem is here[http://rubyforge.org/frs/download.ph
11
11
 
12
12
  == Features
13
13
 
14
- * clean encapsulation of the Thrift API
14
+ * Transparent connection management
15
+ * Configurable failover and retry backoff
15
16
  * Ruby 1.9 compatibility
16
17
 
17
18
  The Github source repository is {here}[http://github.com/fauna/thrift_client/]. Patches and contributions are very welcome.
18
19
 
20
+ == Usage
21
+
22
+ Instantiate a client:
23
+
24
+ client = ThriftClient.new(CassandraRb::Client, '127.0.0.1:9160', :retries => 2)
25
+
26
+ 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.
27
+
28
+ client.get_string_list_property("keyspaces")
29
+
30
+ On failures, the client will try the remaining servers in the list before giving up. See ThriftClient for more.
31
+
19
32
  == Installation
20
33
 
21
34
  You need Ruby 1.8 or 1.9. If you have those, just run:
@@ -0,0 +1,22 @@
1
+
2
+ module Thrift
3
+ class BufferedTransport
4
+ def timeout=(timeout)
5
+ @transport.timeout = timeout
6
+ end
7
+
8
+ def timeout
9
+ @transport.timeout
10
+ end
11
+ end
12
+
13
+ module Client
14
+ def timeout=(timeout)
15
+ @iprot.trans.timeout = timeout
16
+ end
17
+
18
+ def timeout
19
+ @iprot.trans.timeout
20
+ end
21
+ end
22
+ end
data/lib/thrift_client.rb CHANGED
@@ -1,28 +1,47 @@
1
1
 
2
2
  require 'rubygems'
3
3
  require 'thrift'
4
+ require 'thrift_client/thrift'
4
5
 
5
6
  class ThriftClient
6
7
 
8
+ class NoServersAvailable < StandardError; end
9
+
7
10
  DEFAULTS = {
8
11
  :protocol => Thrift::BinaryProtocol,
9
12
  :transport => Thrift::FramedTransport,
10
- :socket_timeout => 1,
11
13
  :randomize_server_list => true,
12
14
  :exception_classes => [
13
15
  IOError,
14
16
  Thrift::Exception,
15
17
  Thrift::ProtocolException,
16
18
  Thrift::ApplicationException,
17
- Thrift::TransportException],
19
+ Thrift::TransportException,
20
+ NoServersAvailable],
18
21
  :raise => true,
19
22
  :retries => nil,
20
- :server_retry_period => nil
23
+ :server_retry_period => nil,
24
+ :timeouts => Hash.new(1),
25
+ :defaults => {}
21
26
  }.freeze
22
27
 
23
28
  attr_reader :client, :client_class, :server_list, :options
24
29
 
25
- class NoServersAvailable < StandardError; end
30
+ =begin rdoc
31
+ Create a new ThriftClient instance. Accepts an internal Thrift client class (such as CassandraRb::Client), a list of servers with ports, and optional parameters.
32
+
33
+ Valid optional parameters are:
34
+
35
+ <tt>:protocol</tt>:: Which Thrift protocol to use. Defaults to <tt>Thrift::BinaryProtocol</tt>.
36
+ <tt>:transport</tt>:: Which Thrift transport to use. Defaults to <tt>Thrift::FramedTransport</tt>.
37
+ <tt>:randomize_server_list</tt>:: Whether to connect to the servers randomly, instead of in order. Defaults to <tt>true</tt>.
38
+ <tt>:raise</tt>:: Whether to reraise errors if no responsive servers are found. Defaults to <tt>true</tt>.
39
+ <tt>:retries</tt>:: How many times to retry a request. Defaults to the number of servers defined.
40
+ <tt>:server_retry_period</tt>:: How long to wait before trying to reconnect after marking all servers as down. Defaults to <tt>nil</tt> (do not wait).
41
+ <tt>:timeouts</tt>:: Specify timeouts on a per-method basis. Defaults to 1 second for everything. (Per-method values only work with <tt>Thrift::BufferedTransport</tt>.)
42
+ <tt>:defaults</tt>:: Specify defaults to return on a per-method basis, if <tt>:raise</tt> is set to false.
43
+
44
+ =end rdoc
26
45
 
27
46
  def initialize(client_class, servers, options = {})
28
47
  @options = DEFAULTS.merge(options)
@@ -31,10 +50,12 @@ class ThriftClient
31
50
  @retries = options[:retries] || @server_list.size
32
51
  @server_list = @server_list.sort_by { rand } if @options[:randomize_server_list]
33
52
 
53
+ @set_timeout = @options[:transport].instance_methods.include?("timeout=")
34
54
  @live_server_list = @server_list.dup
35
55
  @last_retry = Time.now
36
56
  end
37
57
 
58
+ # Force the client to disconnect from the server.
38
59
  def disconnect!
39
60
  @transport.close rescue nil
40
61
  @client = nil
@@ -42,31 +63,39 @@ class ThriftClient
42
63
 
43
64
  private
44
65
 
45
- def method_missing(*args)
66
+ def method_missing(method_name, *args)
46
67
  connect! unless @client
47
- @client.send(*args)
48
- rescue *@options[:exception_classes]
68
+ set_timeout!(method_name) if @set_timeout
69
+ @client.send(method_name, *args)
70
+ rescue *@options[:exception_classes] => e
49
71
  tries ||= @retries
50
72
  tries -= 1
51
- if tries.zero?
52
- raise if @options[:raise]
73
+ if tries.zero? or e.is_a?(NoServersAvailable)
74
+ handle_exception(e, method_name, args)
53
75
  else
54
76
  disconnect!
55
77
  retry
56
78
  end
57
- rescue NoServersAvailable
58
- raise if @options[:raise]
59
79
  end
60
80
 
81
+ def set_timeout!(method_name)
82
+ @client.timeout = @options[:timeouts][:method_name.to_sym]
83
+ end
84
+
85
+ def handle_exception(e, method_name, args)
86
+ raise e if @options[:raise]
87
+ @options[:defaults][method_name.to_sym]
88
+ end
89
+
61
90
  def connect!
62
91
  server = next_server.to_s.split(":")
63
92
  raise ArgumentError, 'Servers must be in the form "host:port"' if server.size != 2
64
-
93
+
65
94
  @transport = @options[:transport].new(
66
- Thrift::Socket.new(server.first, server.last.to_i, @options[:socket_timeout]))
95
+ Thrift::Socket.new(server.first, server.last.to_i, @options[:timeouts].default))
67
96
  @transport.open
68
97
  @client = @client_class.new(@options[:protocol].new(@transport, false))
69
- end
98
+ end
70
99
 
71
100
  def next_server
72
101
  if @live_server_list.empty?
@@ -23,13 +23,23 @@ class ThriftClientTest < Test::Unit::TestCase
23
23
  ThriftClient.new(ScribeThrift::Client, @servers.first, :raise => false).Log(@entry)
24
24
  end
25
25
  end
26
+
27
+ def test_dont_raise_with_defaults
28
+ client = ThriftClient.new(ScribeThrift::Client, @servers.first, :raise => false, :defaults => {:Log => 1})
29
+ assert_equal 1, client.Log(@entry)
30
+ end
31
+
32
+ def test_defaults_dont_override_no_method_error
33
+ client = ThriftClient.new(ScribeThrift::Client, @servers, :raise => false, :defaults => {:Missing => 2})
34
+ assert_raises(NoMethodError) { client.Missing(@entry) }
35
+ end
26
36
 
27
37
  def test_random_server_list
28
38
  @lists = []
29
39
  @lists << ThriftClient.new(ScribeThrift::Client, @servers).server_list while @lists.size < 10
30
40
  assert @lists.uniq.size > 1
31
41
  end
32
-
42
+
33
43
  def test_random_fall_through
34
44
  assert_nothing_raised do
35
45
  10.times { ThriftClient.new(ScribeThrift::Client, @servers).Log(@entry) }
@@ -2,16 +2,16 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{thrift_client}
5
- s.version = "0.1.1"
5
+ s.version = "0.1.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"]
9
9
  s.cert_chain = ["/Users/eweaver/p/configuration/gem_certificates/evan_weaver-original-public_cert.pem"]
10
- s.date = %q{2009-10-14}
10
+ s.date = %q{2009-10-19}
11
11
  s.description = %q{A Thrift client wrapper that encapsulates some common failover behavior.}
12
12
  s.email = %q{}
13
- s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README", "lib/thrift_client.rb"]
14
- s.files = ["CHANGELOG", "LICENSE", "Manifest", "README", "Rakefile", "lib/thrift_client.rb", "test/test_helper.rb", "test/thrift_client_test.rb", "thrift_client.gemspec"]
13
+ s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README", "lib/thrift_client.rb", "lib/thrift_client/thrift.rb"]
14
+ 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"]
15
15
  s.homepage = %q{http://blog.evanweaver.com/files/doc/fauna/thrift_client/}
16
16
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Thrift_client", "--main", "README"]
17
17
  s.require_paths = ["lib"]
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thrift_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Weaver
@@ -30,7 +30,7 @@ cert_chain:
30
30
  yZ0=
31
31
  -----END CERTIFICATE-----
32
32
 
33
- date: 2009-10-14 00:00:00 -07:00
33
+ date: 2009-10-19 00:00:00 -07:00
34
34
  default_executable:
35
35
  dependencies:
36
36
  - !ruby/object:Gem::Dependency
@@ -54,6 +54,7 @@ extra_rdoc_files:
54
54
  - LICENSE
55
55
  - README
56
56
  - lib/thrift_client.rb
57
+ - lib/thrift_client/thrift.rb
57
58
  files:
58
59
  - CHANGELOG
59
60
  - LICENSE
@@ -61,6 +62,7 @@ files:
61
62
  - README
62
63
  - Rakefile
63
64
  - lib/thrift_client.rb
65
+ - lib/thrift_client/thrift.rb
64
66
  - test/test_helper.rb
65
67
  - test/thrift_client_test.rb
66
68
  - thrift_client.gemspec
metadata.gz.sig CHANGED
Binary file