Class: AbstractThriftClient

Inherits:
Object
  • Object
show all
Includes:
ThriftHelpers
Defined in:
lib/thrift_client/abstract_thrift_client.rb

Direct Known Subclasses

ThriftClient

Constant Summary collapse

DISCONNECT_ERRORS =
[
  IOError,
  Thrift::Exception,
  Thrift::ApplicationException,
  Thrift::TransportException
]
DEFAULT_WRAPPED_ERRORS =
[
  Thrift::ApplicationException,
  Thrift::TransportException,
]
DEFAULTS =
{
  :protocol => Thrift::BinaryProtocol,
  :protocol_extra_params => [],
  :transport => Thrift::Socket,
  :transport_wrapper => Thrift::FramedTransport,
  :raise => true,
  :defaults => {},
  :exception_classes => DISCONNECT_ERRORS,
  :exception_class_overrides => [],
  :retries => 0,
  :server_retry_period => 1,
  :server_max_requests => nil,
  :retry_overrides => {},
  :wrapped_exception_classes => DEFAULT_WRAPPED_ERRORS,
  :connect_timeout => 0.1,
  :timeout => 1,
  :timeout_overrides => {},
  :cached_connections => false
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client_class, servers, options = {}) ⇒ AbstractThriftClient

Returns a new instance of AbstractThriftClient.

[View source]

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/thrift_client/abstract_thrift_client.rb', line 49

def initialize(client_class, servers, options = {})
  @options = DEFAULTS.merge(options)
  @options[:server_retry_period] ||= 0

  @client_class = client_class
  @server_list = Array(servers).collect do |s|
    Server.new(s, @client_class, @options)
  end.sort_by { rand }

  @current_server = @server_list.first

  @callbacks = {}
  @client_methods = []
  @client_class.instance_methods.each do |method_name|
    if method_name != 'send_message' && method_name =~ /^send_(.*)$/
      instance_eval("def #{$1}(*args); handled_proxy(:'#{$1}', *args); end", __FILE__, __LINE__)
      @client_methods << $1
    end
  end
  @request_count = 0
  self.class.create_wrapped_exception_classes(@client_class, @options[:wrapped_exception_classes])
end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.


36
37
38
# File 'lib/thrift_client/abstract_thrift_client.rb', line 36

def client
  @client
end

#client_classObject (readonly)

Returns the value of attribute client_class.


36
37
38
# File 'lib/thrift_client/abstract_thrift_client.rb', line 36

def client_class
  @client_class
end

#client_methodsObject (readonly)

Returns the value of attribute client_methods.


36
37
38
# File 'lib/thrift_client/abstract_thrift_client.rb', line 36

def client_methods
  @client_methods
end

#current_serverObject (readonly)

Returns the value of attribute current_server.


36
37
38
# File 'lib/thrift_client/abstract_thrift_client.rb', line 36

def current_server
  @current_server
end

#last_clientObject (readonly)

Returns the value of attribute last_client.


36
37
38
# File 'lib/thrift_client/abstract_thrift_client.rb', line 36

def last_client
  @last_client
end

#optionsObject (readonly)

Returns the value of attribute options.


36
37
38
# File 'lib/thrift_client/abstract_thrift_client.rb', line 36

def options
  @options
end

#server_listObject (readonly)

Returns the value of attribute server_list.


36
37
38
# File 'lib/thrift_client/abstract_thrift_client.rb', line 36

def server_list
  @server_list
end

Class Method Details

.create_wrapped_exception_classes(client_class, wrapped_exception_classes = DEFAULT_WRAPPED_ERRORS) ⇒ Object

[View source]

38
39
40
41
42
43
44
45
46
47
# File 'lib/thrift_client/abstract_thrift_client.rb', line 38

def self.create_wrapped_exception_classes(client_class, wrapped_exception_classes = DEFAULT_WRAPPED_ERRORS)
  wrapped_exception_classes.map do |exception_klass|
    name = exception_klass.to_s.split('::').last
    begin
      client_class.const_get(name)
    rescue NameError
      client_class.const_set(name, Class.new(exception_klass))
    end
  end
end

Instance Method Details

#add_callback(callback_type, &block) ⇒ Object

Adds a callback that will be invoked at a certain time. The valid callback types are:

:post_connect  - should accept a single AbstractThriftClient argument, which is the client object to
                 which the callback was added. Called after a connection to the remote thrift server
                 is established.
:before_method - should accept a single method name argument. Called before a method is invoked on the
                 thrift server.
:on_exception  - should accept 2 args: an Exception instance and a method name. Called right before the
                 exception is raised.
[View source]

80
81
82
83
84
85
86
87
88
89
90
# File 'lib/thrift_client/abstract_thrift_client.rb', line 80

def add_callback(callback_type, &block)
  case callback_type
  when :post_connect, :before_method, :on_exception
    @callbacks[callback_type] ||= []
    @callbacks[callback_type].push(block)
    # Allow chaining
    return self
  else
    return nil
  end
end

#connect!(method = nil) ⇒ Object

Force the client to connect to the server. Not necessary to be called as the connection will be made on the first RPC method call.

[View source]

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/thrift_client/abstract_thrift_client.rb', line 99

def connect!(method = nil)
  start_time ||= Time.now
  @current_server = next_live_server
  @client = @current_server.client
  @last_client = @client
  do_callbacks(:post_connect, self)
rescue IOError, Thrift::TransportException
  disconnect!(true)
  timeout = timeout(method)
  if timeout && Time.now - start_time > timeout
    no_servers_available!
  else
    retry
  end
end

#disconnect!(error = false) ⇒ Object

[View source]

115
116
117
118
119
120
121
122
123
124
# File 'lib/thrift_client/abstract_thrift_client.rb', line 115

def disconnect!(error = false)
  if @current_server
    @current_server.mark_down!(@options[:server_retry_period]) if error
    @current_server.close
  end

  @client = nil
  @current_server = nil
  @request_count = 0
end

#inspectObject

[View source]

92
93
94
# File 'lib/thrift_client/abstract_thrift_client.rb', line 92

def inspect
  "<#{self.class}(#{client_class}) @current_server=#{@current_server}>"
end