Skip to content

Instantly share code, notes, and snippets.

@alex-magana
Created June 13, 2019 20:26
Show Gist options
  • Save alex-magana/7f07fe73caddf56b60758e1f0b5b9878 to your computer and use it in GitHub Desktop.
Save alex-magana/7f07fe73caddf56b60758e1f0b5b9878 to your computer and use it in GitHub Desktop.
# Circuit Breaker
# - Circuit starts in a "closed" state.
# - Here, all calls to a given service go through
# - Consecutive failures are recorded.
# - When threshold is reached, circuit trips and the circuit gets into an "open" state.
# - In open state, calls to a given service raise CircuitBrokenException
# - Circuit remains "open" until failure timeout elapses
# - After failure timeout elapses, circuit gets into "half-open" state
# - Here, a call to aservice will go through
# - If the call fails, the circuit goes back to "open" state
# - If the call succeeds, the circuit goes back to "closed" state and failuer count is reset
# - Invocation timeout sets the amount of time to wait for a response to be returned for a given request
# https://github.com/wsargent/circuit_breaker
# http://rdoc.info/projects/wsargent/circuit_breaker
require "circuit_breaker"
require "rest-client"
require "alephant/logger"
class Client
def fetch(url)
response = request(url)
return unless response
::JSON.parse(response)
end
def request(url)
attempts ||= 3
rq ||= RestClient::Request
headers = { "Accept" => "application/json" }
rq.execute(:method => :get,
:headers => headers,
:url => url).tap do
log_fetch_success(url)
response
end
rescue RestClient::ResourceNotFound => e
log_fetch_not_found url, e
return nil
rescue RestClient::RequestFailed => e
retry unless (attempts -= 1).zero?
log_fetch_failure(url, e)
nil
end
def log_fetch_success(url)
logger.info(
"event" => "RequestSuccess",
"url" => url,
"method" => "#{self.class}#request"
)
end
def log_fetch_failure(url, e)
logger.info(
"event" => "RequestFailure",
"url" => url,
"error" => e,
"method" => "#{self.class}#request"
)
end
def log_fetch_not_found url, e
logger.info(
"event" => "ResourceNotFound",
"url" => url,
"error" => e,
"method" => "#{self.class}#request"
)
end
circuit_method :request
circuit_handler do |handler|
threshold = instance.app_config[:CIRCUIT_BREAKER_FAILURES_THRESHOLD].to_i
timeout = instance.app_config[:CIRCUIT_BREAKER_TIMEOUT].to_i
handler.logger = Alephant::Logger.get_logger
handler.failure_threshold = threshold
handler.failure_timeout = timeout
handler.invocation_timeout = 3
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment