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.



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



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.


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.



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



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



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

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