class AbstractThriftClient
Constants
- APPLICATION_ERRORS
- DEFAULTS
DEFAULT_BEFORE_METHOD = Proc.new {|method_name| puts “prepare call #{method_name} method.”} DEFAULT_AFTER_METHOD = Proc.new {|method_name| puts “called #{method_name} method.”} DEFAULT_ON_EXCEPTION = Proc.new {|method_name, e| puts “call #{method_name} method ouccur exception.”; raise e}
- DISCONNECT_ERRORS
Public Class Methods
new(options = {})
click to toggle source
# File lib/thrift_client/abstract_thrift_client.rb, line 44 def initialize(options = {}) user_options = initialize_options(options) servers = parse_servers(options["servers"]) #initialize options @options = DEFAULTS.merge(user_options) #initialize servers info @server_list = servers.collect do |s| Server.new(s, @options) end.sort_by { rand } @callbacks = {} #initialize client methods @client_methods = [] @options[:client_class].instance_methods.each do |method_name| if method_name != 'send_message' && method_name =~ /^send_(.*)$/ instance_eval("def #{$1}(*args); handle_method(:'#{$1}', *args); end", __FILE__, __LINE__) @client_methods << $1 end end @retry = @options[:retry] @state = 1 end
Public Instance Methods
add_callback(callback_type, &block)
click to toggle source
# File lib/thrift_client/abstract_thrift_client.rb, line 71 def add_callback(callback_type, &block) case callback_type when :before_method, :after_method, :on_exception @callbacks[callback_type] ||= [] @callbacks[callback_type].push(block) else raise ArgumentError.new("Unknown callback type #{callback_type},only support before_method|after_method|on_exception") end return self end
destroy()
click to toggle source
# File lib/thrift_client/abstract_thrift_client.rb, line 122 def destroy @state = -1 @server_list.each { |server| begin server.destroy if server rescue Exception => e puts "destroy server #{server} error, #{e.message}, #{e.backtrace}" end } end
handle_method(method_name, *args)
click to toggle source
retry two times
# File lib/thrift_client/abstract_thrift_client.rb, line 83 def handle_method(method_name, *args) check_state server = next_server do_callbacks(:before_method, method_name) result = server.with do |client| tries = 0 begin ensure_connected client client.send(method_name, *args) rescue *@options[:application_exception_classes] => e if(@callbacks[:on_exception] && @callbacks[:on_exception].length > 0) do_callbacks(:on_exception, method_name, e) else raise e end rescue *@options[:disconnect_exception_classes] => e # if e instance_of? Thrift::TransportException && e.type == Thrift::TransportException::TIMED_OUT begin if client.connected? client.disconnect end rescue Exception => e puts "disconnect error" end if tries < @retry # retry two times tries += 1 retry end if(@callbacks[:on_exception] && @callbacks[:on_exception].length > 0) do_callbacks(:on_exception, method_name, e) else raise e end end end do_callbacks(:after_method, method_name) result end
Private Instance Methods
check_state()
click to toggle source
# File lib/thrift_client/abstract_thrift_client.rb, line 154 def check_state if @state < 0 raise ClientAlreadyDestroyedError, "Client had already destroyed." end end
do_callbacks(callback_type_sym, *args)
click to toggle source
Calls all callbacks of the specified type with the given args
# File lib/thrift_client/abstract_thrift_client.rb, line 175 def do_callbacks(callback_type_sym, *args) return unless @callbacks[callback_type_sym] @callbacks[callback_type_sym].each do |callback| callback.call(*args) end end
ensure_connected(client)
click to toggle source
确保连接正常,在遇到异常时,重试一次
# File lib/thrift_client/abstract_thrift_client.rb, line 136 def ensure_connected(client) try = true begin if !client.connected? client.connect end client rescue Exception => e client.disconnect if try try = false retry else raise end end end
initialize_options(options)
click to toggle source
# File lib/thrift_client/abstract_thrift_client.rb, line 182 def initialize_options(options) user_options = {} if options["client_class"] != nil client_class_str = options["client_class"].strip if client_class_str.empty? raise ArgumentError, "client class is empty string" end begin client_class = eval(client_class_str) flag = client_class.ancestors.include?(Thrift::Client) rescue Exception => e raise ArgumentError, "could not find class #{client_class_str}" end if flag user_options.store(:client_class, client_class) else raise ArgumentError, "client class [#{client_class}] is not a subclass of Thrift::Client" end else raise ArgumentError, "client class is nil" end if options["protocol"] != nil case options["protocol"] when "compact" protocol_class = Thrift::CompactProtocol when "binary" protocol_class = Thrift::BinaryProtocol when "json" protocol_class = Thrift::JsonProtocol else raise ArgumentError, "Unknown protocol type [#{options["protocol"]}], use compact|binary|json" end user_options.store(:protocol, protocol_class) end if options["transport"] != nil case options["transport"] when "socket" transport_class = Thrift::Socket when "unix_socket" transport_class = Thrift::UNIXSocket when "eventmachine" transport_class = Thrift::EventMachineTransport when "em" transport_class = Thrift::EventMachineTransport else raise ArgumentError, "Unknown transport type [#{options["transport"]}], use socket|unix_socket|em(eventmachine)" end user_options.store(:transport, transport_class) end if options["framed"] != nil if options["framed"] != true user_options.store(:transport_wrapper, Thrift::BufferedTransport) end end if options["disconnect_exception_classes"] != nil user_define_disconnect_exceptions = options["disconnect_exception_classes"].split(",") user_define_disconnect_exceptions.each do |exception| exception_class = eval(exception) if exception_class.ancestors.include?(Exception) DISCONNECT_ERRORS.push(exception_class) else raise ArgumentError, "exception class [#{exception_class}] is not a subclass of Exception" end end DISCONNECT_ERRORS.uniq! end user_options.store(:disconnect_exception_classes, DISCONNECT_ERRORS) if options["application_exception_classes"] != nil user_define_application_exceptions = options["application_exception_classes"].split(",") user_define_application_exceptions.each do |exception| exception_class = eval(exception) if exception_class.ancestors.include?(Exception) APPLICATION_ERRORS.push(exception_class) else raise ArgumentError, "exception class [#{exception_class}] is not a subclass of Exception" end end APPLICATION_ERRORS.uniq! end user_options.store(:application_exception_classes, APPLICATION_ERRORS) if options["size"] != nil user_options.store(:size, options["size"].to_i) end if options["timeout"] != nil user_options.store(:timeout, options["timeout"].to_i) end if options["multiplexed"] != nil user_options.store(:multiplexed, options["multiplexed"] || options["multiplexed"] == 'true') end if options["retry"] != nil user_options.store(:retry, options["retry"]) end user_options end
next_server()
click to toggle source
# File lib/thrift_client/abstract_thrift_client.rb, line 160 def next_server @current_server_index ||= 0 @server_list.length.times do |i| index = (1 + @current_server_index + i) % @server_list.length @current_server_index = index return @server_list[index] end end
no_available_server()
click to toggle source
# File lib/thrift_client/abstract_thrift_client.rb, line 169 def no_available_server servers = @server_list.map { |s| s.to_s }.join(',') raise NoAvailableServerError, "No available servers in [#{servers}]." end
parse_servers(servers_string)
click to toggle source
# File lib/thrift_client/abstract_thrift_client.rb, line 286 def parse_servers(servers_string) if servers_string != nil servers_string = servers_string.strip if servers_string.empty? raise ArgumentError, "servers info is empty string" end return servers_string.split(",") else raise ArgumentError, "servers info is nil" end end