Skip to content
This repository has been archived by the owner on Sep 18, 2021. It is now read-only.

Commit

Permalink
Merge pull request #38 from twitter/connection-reuse-fixes
Browse files Browse the repository at this point in the history
Connection reuse fixes
  • Loading branch information
Stu Hood committed May 15, 2012
2 parents 5b8649b + 2490029 commit 6af7317
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 23 deletions.
19 changes: 9 additions & 10 deletions lib/gizzard/nameserver.rb
Expand Up @@ -145,33 +145,33 @@ def initialize(*hosts)
end end


def get_shards(ids) def get_shards(ids)
ids.map {|id| with_retry("get_shards", 1) { random_client.get_shard(id) } } ids.map {|id| with_retry(1) { random_client.get_shard(id) } }
end end


def reload_updated_forwardings def reload_updated_forwardings
opname = "reload_updated_forwardings" opname = "reload_updated_forwardings"
on_all_servers opname do |c| on_all_servers opname do |c|
with_retry(opname, MAX_BACKOFF_SECS/4) { c.reload_updated_forwardings } with_retry(MAX_BACKOFF_SECS/4) { c.reload_updated_forwardings }
end end
end end


def reload_config def reload_config
opname = "reload_config" opname = "reload_config"
on_all_servers opname do |c| on_all_servers opname do |c|
with_retry(opname, MAX_BACKOFF_SECS/4) { c.reload_config } with_retry(MAX_BACKOFF_SECS/4) { c.reload_config }
end end
end end


def copy_shard(*shards) def copy_shard(*shards)
with_retry("copy_shard", MAX_BACKOFF_SECS/2) { random_client.copy_shard(*shards) } with_retry(MAX_BACKOFF_SECS/2) { random_client.copy_shard(*shards) }
end end


def repair_shards(*shards) def repair_shards(*shards)
with_retry("repair_shards", MAX_BACKOFF_SECS/2) { random_client.repair_shard(*shards) } with_retry(MAX_BACKOFF_SECS/2) { random_client.repair_shard(*shards) }
end end


def diff_shards(*shards) def diff_shards(*shards)
with_retry("diff_shards", MAX_BACKOFF_SECS/2) { random_client.diff_shards(*shards) } with_retry(MAX_BACKOFF_SECS/2) { random_client.diff_shards(*shards) }
end end


def respond_to?(method) def respond_to?(method)
Expand All @@ -182,7 +182,7 @@ def method_missing(method, *args, &block)
if client.respond_to?(method) if client.respond_to?(method)
# operations without specialized backoff use a backoff which assumes cheap, easily # operations without specialized backoff use a backoff which assumes cheap, easily
# retryable operations: if this isn't the case, methods should specialize as above # retryable operations: if this isn't the case, methods should specialize as above
with_retry(method, 0.1) { random_client.send(method, *args, &block) } with_retry(0.1) { random_client.send(method, *args, &block) }
else else
super super
end end
Expand Down Expand Up @@ -299,14 +299,13 @@ def create_client(host)


private private


def with_retry(opname, min_backoff_secs) def with_retry(min_backoff_secs)
times ||= @retries times ||= @retries
yield yield
rescue SystemExit => e rescue SystemExit => e
STDERR.puts "\nExiting immediately for #{e.to_s}" STDERR.puts "Exiting immediately for #{e.to_s}"
raise raise
rescue Exception => e 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 STDERR.puts "Retrying #{times} more time#{'s' if times > 1}..." if times > 0
times -= 1 times -= 1
sleep_time = [min_backoff_secs, MAX_BACKOFF_SECS / [times, 1].max].max sleep_time = [min_backoff_secs, MAX_BACKOFF_SECS / [times, 1].max].max
Expand Down
10 changes: 5 additions & 5 deletions lib/gizzard/thrift.rb
Expand Up @@ -299,12 +299,12 @@ class Manager < GizzmoService
# (log entries are binary, but this client doesn't support labeling them as such) # (log entries are binary, but this client doesn't support labeling them as such)


# create or get a log, returning a binary id for that log # create or get a log, returning a binary id for that log
thrift_method :log_create, string, field(:log_name, string, 1) thrift_method :log_create, string, field(:log_name, string, 1), :throws => exception(GizzardException)
thrift_method :log_get, string, field(:log_name, string, 1) thrift_method :log_get, string, field(:log_name, string, 1), :throws => exception(GizzardException)
# given a log id, push/pop/peek binary data on that log # given a log id, push/pop/peek binary data on that log
thrift_method :log_entry_push, void, field(:log_id, string, 1), field(:log_entry, struct(LogEntry), 2) thrift_method :log_entry_push, void, field(:log_id, string, 1), field(:log_entry, struct(LogEntry), 2), :throws => exception(GizzardException)
thrift_method :log_entry_peek, list(struct(LogEntry)), field(:log_id, string, 1), field(:count, i32, 2) thrift_method :log_entry_peek, list(struct(LogEntry)), field(:log_id, string, 1), field(:count, i32, 2), :throws => exception(GizzardException)
thrift_method :log_entry_pop, void, field(:log_id, string, 1), field(:log_entry_id, i32, 2) thrift_method :log_entry_pop, void, field(:log_id, string, 1), field(:log_entry_id, i32, 2), :throws => exception(GizzardException)
end end




Expand Down
14 changes: 6 additions & 8 deletions lib/vendor/thrift_client/simple.rb
Expand Up @@ -34,7 +34,7 @@ module Simple
# failed rpc # failed rpc
SOCKETS = Hash.new SOCKETS = Hash.new
previous_sig = trap("EXIT") do previous_sig = trap("EXIT") do
SOCKETS.each do |sock| SOCKETS.each do |host,sock|
begin begin
sock.close sock.close
rescue rescue
Expand All @@ -44,12 +44,10 @@ module Simple


# establish or reuse a persistent connection for the given host # establish or reuse a persistent connection for the given host
def self.sock(host, port) def self.sock(host, port)
if SOCKETS.key? host if !SOCKETS.key?(host)
SOCKETS[host] SOCKETS[host] = TCPSocket.new(host, port)
else
sock = TCPSocket.new(host, port)
SOCKETS[host] = sock
end end
SOCKETS[host]
end end


# attempt to close and clear the connection for the given host # attempt to close and clear the connection for the given host
Expand Down Expand Up @@ -355,11 +353,11 @@ def _proxy(method_name, *args)
arg_struct = arg_class.new(*args) arg_struct = arg_class.new(*args)
begin begin
sock = ThriftClient::Simple.sock(@host, @port) sock = ThriftClient::Simple.sock(@host, @port)
packed = ThriftClient::Simple.pack_request(method_name, arg_struct, @framed) sock.write(ThriftClient::Simple.pack_request(method_name, arg_struct, @framed))
wrote = sock.write(packed)
rv = ThriftClient::Simple.read_response(sock, rv_class, @framed) rv = ThriftClient::Simple.read_response(sock, rv_class, @framed)
rv[2] rv[2]
rescue Exception => e rescue Exception => e
STDERR.puts "\nException for #{method_name} on #{@host}: #{e.to_s}: #{e.description rescue "(no description)"}"
ThriftClient::Simple.sock_close(@host) ThriftClient::Simple.sock_close(@host)
raise e raise e
end end
Expand Down

0 comments on commit 6af7317

Please sign in to comment.