Permalink
Browse files

Cache connections per-host for the process lifetime, or until the fir…

…st exception
  • Loading branch information...
1 parent e0c01e8 commit e9fe4c91d72fb6fed064fedabb9f53ed22de94d0 @stuhood stuhood committed May 9, 2012
Showing with 42 additions and 6 deletions.
  1. +3 −0 lib/gizzard/nameserver.rb
  2. +39 −6 lib/vendor/thrift_client/simple.rb
@@ -302,6 +302,9 @@ def create_client(host)
def with_retry(opname, min_backoff_secs)
times ||= @retries
yield
+ rescue SystemExit => e
+ STDERR.puts "\nExiting immediately for #{e.to_s}"
+ raise
rescue Exception => e
STDERR.puts "\nException for #{opname}: #{e.to_s}: #{e.description rescue "(no description)"}"
STDERR.puts "Retrying #{times} more time#{'s' if times > 1}..." if times > 0
@@ -29,6 +29,41 @@ module Simple
I32 => 4,
}
+ # a hash of persistent connections that should be torn down by the exit handler:
+ # connections are reused for the lifetime of the process, or until their first
+ # failed rpc
+ SOCKETS = Hash.new
+ previous_sig = trap("EXIT") do
+ SOCKETS.each do |sock|
+ begin
+ sock.close
+ rescue
+ end
+ end
+ end
+ if !previous_sig.nil?
+ raise Exception.new("Cannot override EXIT system handler: #{previous_sig}.")
+ end
+
+ # establish or reuse a persistent connection for the given host
+ def self.sock(host, port)
+ if SOCKETS.key? host
+ SOCKETS[host]
+ else
+ sock = TCPSocket.new(host, port)
+ SOCKETS[host] = sock
+ end
+ end
+
+ # attempt to close and clear the connection for the given host
+ def self.sock_close(host)
+ if SOCKETS.key? host
+ sock = SOCKETS[host]
+ begin; sock.close; rescue; end
+ SOCKETS.delete(host)
+ end
+ end
+
module ComplexType
module Extends
def type_id=(n)
@@ -321,16 +356,14 @@ def _proxy(method_name, *args)
cls = self.class.ancestors.find { |cls| cls.respond_to?(:_arg_structs) and cls._arg_structs[method_name.to_sym] }
arg_class, rv_class = cls._arg_structs[method_name.to_sym]
arg_struct = arg_class.new(*args)
- @sock ||= TCPSocket.new(@host, @port)
begin
+ sock = ThriftClient::Simple.sock(@host, @port)
packed = ThriftClient::Simple.pack_request(method_name, arg_struct, @framed)
- wrote = @sock.write(packed)
- rv = ThriftClient::Simple.read_response(@sock, rv_class, @framed)
+ wrote = sock.write(packed)
+ rv = ThriftClient::Simple.read_response(sock, rv_class, @framed)
rv[2]
rescue Exception => e
- # attempt to close the socket and nil it, then re-raise the original exception
- begin; @sock.close; rescue; end
- @sock = nil
+ ThriftClient::Simple.sock_close(@host)
raise e
end
end

0 comments on commit e9fe4c9

Please sign in to comment.