-
Notifications
You must be signed in to change notification settings - Fork 170
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds the ability to retry for the pool of connection if specified in makara config #338
base: master
Are you sure you want to change the base?
Changes from 8 commits
975a752
923bc43
a1e6ee0
4459e81
50f0393
64337e4
90bc737
d43a219
992ef92
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,3 +17,4 @@ spec/reports | |
test/tmp | ||
test/version_tmp | ||
tmp | ||
.idea |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,8 +24,12 @@ def hijack_method(*method_names) | |
|
||
method_names.each do |method_name| | ||
define_method method_name do |*args, &block| | ||
appropriate_connection(method_name, args) do |con| | ||
con.send(method_name, *args, &block) | ||
|
||
makara_config = @config.with_indifferent_access[:makara] | ||
if makara_config.key?(:retry_exceptions) && (retry_exceptions = makara_config[:retry_exceptions]).present? | ||
_execute_with_connection_and_retry_exceptions(retry_exceptions, args, block, method_name) | ||
else | ||
_execute_with_connection(args, block, method_name) | ||
end | ||
end | ||
end | ||
|
@@ -162,6 +166,43 @@ def any_connection | |
end | ||
end | ||
|
||
MAX_RETRY_COUNT = 10 | ||
|
||
def _execute_with_connection_and_retry_exceptions(retry_exceptions, args, block, method_name) | ||
begin | ||
should_retry = false | ||
potentially_stale_connection = nil | ||
|
||
appropriate_connection(method_name, args) do |con| | ||
con.send(method_name, *args, &block) | ||
potentially_stale_connection = con | ||
end | ||
|
||
rescue Exception => actual_exception | ||
retry_attempts = retry_exceptions.inject({}) { |memo, retry_exception| memo[retry_exception['name']] = 0; memo } | ||
retry_exceptions.each do |retry_exception| | ||
if actual_exception.class.to_s == retry_exception['name'] | ||
potentially_stale_connection.disconnect! | ||
sleep retry_exception['time_between_retries_in_seconds'] || 0.1 | ||
retry_attempt = (retry_attempts[actual_exception.class.to_s] += 1) | ||
|
||
max_attempts = retry_exception['retry_count'] || MAX_RETRY_COUNT | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better name would be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is a MAX count as well if you see the condition below :) |
||
if retry_attempt < max_attempts && retry_attempt < MAX_RETRY_COUNT | ||
should_retry = true | ||
end | ||
end | ||
end | ||
retry if should_retry | ||
raise actual_exception | ||
end | ||
end | ||
|
||
def _execute_with_connection(args, block, method_name) | ||
appropriate_connection(method_name, args) do |con| | ||
con.send(method_name, *args, &block) | ||
end | ||
end | ||
|
||
# based on the method_name and args, provide the appropriate connection | ||
# mark this proxy as hijacked so the underlying connection does not attempt to check | ||
# with back with this proxy. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if a bit of randomization here would be useful to avoid a load spike after the instance comes up.