thrift_client 0.1.1 → 0.1.2

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,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