mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-10-06 00:02:08 -04:00
:circuit_breaker
plugin: added support for .on_circuit_open
callback
called when a circuit is open. ```ruby HTTPX.plugin(:circuit_breaker).on_circuit_open do |req| # ... do smth end
This commit is contained in:
parent
03059786b6
commit
eb0291ed87
@ -31,6 +31,16 @@ module HTTPX
|
||||
@circuit_store = orig.instance_variable_get(:@circuit_store).dup
|
||||
end
|
||||
|
||||
%i[circuit_open].each do |meth|
|
||||
class_eval(<<-MOD, __FILE__, __LINE__ + 1)
|
||||
def on_#{meth}(&blk) # def on_circuit_open(&blk)
|
||||
on(:#{meth}, &blk) # on(:circuit_open, &blk)
|
||||
end # end
|
||||
MOD
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def send_requests(*requests)
|
||||
# @type var short_circuit_responses: Array[response]
|
||||
short_circuit_responses = []
|
||||
@ -59,6 +69,12 @@ module HTTPX
|
||||
end
|
||||
|
||||
def on_response(request, response)
|
||||
emit(:circuit_open, request) if try_circuit_open(request, response)
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
def try_circuit_open(request, response)
|
||||
if response.is_a?(ErrorResponse)
|
||||
case response.error
|
||||
when RequestTimeoutError
|
||||
@ -69,8 +85,6 @@ module HTTPX
|
||||
elsif (break_on = request.options.circuit_breaker_break_on) && break_on.call(response)
|
||||
@circuit_store.try_open(request.uri, response)
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -5,7 +5,7 @@ module HTTPX
|
||||
class CircuitStore
|
||||
@circuits: Hash[String, Circuit]
|
||||
|
||||
def try_open: (generic_uri uri, response response) -> void
|
||||
def try_open: (generic_uri uri, response response) -> response?
|
||||
|
||||
def try_respond: (Request request) -> response?
|
||||
|
||||
@ -30,7 +30,7 @@ module HTTPX
|
||||
|
||||
def respond: () -> response?
|
||||
|
||||
def try_open: (response) -> void
|
||||
def try_open: (response) -> response?
|
||||
|
||||
def try_close: () -> void
|
||||
|
||||
@ -52,6 +52,10 @@ module HTTPX
|
||||
|
||||
module InstanceMethods
|
||||
@circuit_store: CircuitStore
|
||||
|
||||
private
|
||||
|
||||
def try_circuit_open: (Request request, response response) -> response?
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -70,6 +70,30 @@ module Requests
|
||||
assert response1 == response2
|
||||
end
|
||||
|
||||
def test_plugin_circuit_breaker_on_circuit_open
|
||||
return unless origin.start_with?("http://")
|
||||
|
||||
unknown_uri = "http://www.qwwqjqwdjqiwdj.com"
|
||||
|
||||
circuit_opened = false
|
||||
session = HTTPX.plugin(:circuit_breaker,
|
||||
circuit_breaker_max_attempts: 1,
|
||||
circuit_breaker_break_in: 2,
|
||||
circuit_breaker_half_open_drip_rate: 1.0)
|
||||
.on_circuit_open { circuit_opened = true }
|
||||
|
||||
# circuit closed
|
||||
response1 = session.get(unknown_uri)
|
||||
verify_error_response(response1)
|
||||
|
||||
# circuit open
|
||||
response2 = session.get(unknown_uri)
|
||||
verify_error_response(response2)
|
||||
assert response2 == response1
|
||||
|
||||
assert circuit_opened
|
||||
end
|
||||
|
||||
# def test_plugin_circuit_breaker_half_open_drip_rate
|
||||
# unknown_uri = "http://www.qwwqjqwdjqiwdj.com"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user