Merge branch 'c-breaker'

This commit is contained in:
HoneyryderChuck 2023-09-29 15:01:00 +01:00
commit 62868f64b3
9 changed files with 28 additions and 20 deletions

View File

@ -51,13 +51,13 @@ module HTTPX
# run all requests through the circuit breaker, see if the circuit is
# open for any of them.
real_requests = requests.each_with_object([]) do |req, real_reqs|
real_requests = requests.each_with_index.with_object([]) do |(req, idx), real_reqs|
short_circuit_response = @circuit_store.try_respond(req)
if short_circuit_response.nil?
real_reqs << req
next
end
short_circuit_responses[requests.index(req)] = short_circuit_response
short_circuit_responses[idx] = short_circuit_response
end
# run requests for the remainder
@ -90,6 +90,7 @@ module HTTPX
@circuit_store.try_open(request.uri, response)
else
@circuit_store.try_close(request.uri)
nil
end
end
end

View File

@ -1,5 +1,7 @@
# frozen_string_literal: true
require "mutex_m"
module HTTPX::Plugins::CircuitBreaker
using HTTPX::URIExtensions
@ -13,18 +15,21 @@ module HTTPX::Plugins::CircuitBreaker
options.circuit_breaker_half_open_drip_rate
)
end
@circuits.extend(Mutex_m)
end
def try_open(uri, response)
circuit = get_circuit_for_uri(uri)
circuit = @circuits.synchronize { get_circuit_for_uri(uri) }
circuit.try_open(response)
end
def try_close(uri)
return unless @circuits.key?(uri.origin) || @circuits.key?(uri.to_s)
circuit = @circuits.synchronize do
return unless @circuits.key?(uri.origin) || @circuits.key?(uri.to_s)
circuit = get_circuit_for_uri(uri)
get_circuit_for_uri(uri)
end
circuit.try_close
end
@ -32,7 +37,7 @@ module HTTPX::Plugins::CircuitBreaker
# if circuit is open, it'll respond with the stored response.
# if not, nil.
def try_respond(request)
circuit = get_circuit_for_uri(request.uri)
circuit = @circuits.synchronize { get_circuit_for_uri(request.uri) }
circuit.respond
end
@ -40,9 +45,7 @@ module HTTPX::Plugins::CircuitBreaker
private
def get_circuit_for_uri(uri)
uri = URI(uri)
if @circuits.key?(uri.origin)
if uri.respond_to?(:origin) && @circuits.key?(uri.origin)
@circuits[uri.origin]
else
@circuits[uri.to_s]

View File

@ -5,7 +5,8 @@ module HTTPX
VERSION: String
type uri = URI::HTTP | URI::HTTPS | string
type http_uri = URI::HTTP | URI::HTTPS
type uri = http_uri | string
type generic_uri = String | URI::Generic
type verb = "OPTIONS" | "GET" | "HEAD" | "POST" | "PUT" | "DELETE" | "TRACE" | "CONNECT" |

View File

@ -5,6 +5,6 @@ module HTTPX
alias host path
def initialize: (URI::HTTP | URI::HTTPS origin, Array[String]? addresses, options options) -> void
def initialize: (http_uri origin, Array[String]? addresses, options options) -> void
end
end

View File

@ -3,17 +3,17 @@ module HTTPX
module CircuitBreaker
class CircuitStore
@circuits: Hash[String, Circuit]
@circuits: Hash[String, Circuit] & Mutex_m
def try_open: (generic_uri uri, response response) -> response?
def try_open: (uri uri, response response) -> response?
def try_respond: (Request request) -> response?
def try_close: (generic_uri uri) -> void
def try_close: (http_uri uri) -> void
private
def get_circuit_for_uri: (generic_uri uri) -> Circuit
def get_circuit_for_uri: (uri uri) -> Circuit
def initialize: (Options & _CircuitOptions options) -> void
end

View File

@ -7,7 +7,7 @@ module HTTPX
module InstanceMethods
private
def build_gateway_socket: (int, URI::HTTP | URI::HTTPS, Options) -> _ToIO
def build_gateway_socket: (int, http_uri, Options) -> _ToIO
end
end
end

View File

@ -2,9 +2,10 @@ module HTTPX
module Plugins
module ResponseCache
CACHEABLE_VERBS: Array[verb]
CACHEABLE_STATUS_CODES: Array[Integer]
def self?.cacheable_request?: (Request request) -> bool
def self?.cacheable_response?: (response response) -> bool
def self?.cacheable_request?: (Request & RequestMethods request) -> bool
def self?.cacheable_response?: (::HTTPX::ErrorResponse | (Response & ResponseMethods) response) -> bool
def self?.cached_response?: (response response) -> bool
class Store
@ -34,6 +35,8 @@ module HTTPX
end
module RequestMethods
@response_cache_key: String
def response_cache_key: () -> String
end

View File

@ -7,7 +7,7 @@ module HTTPX
USER_AGENT: String
attr_reader verb: verb
attr_reader uri: URI::HTTP | URI::HTTPS
attr_reader uri: http_uri
attr_reader headers: Headers
attr_reader body: Body
attr_reader state: Symbol

View File

@ -65,7 +65,7 @@ if [[ "$RUBY_ENGINE" = "ruby" ]] && [[ ${RUBY_VERSION:0:1} = "3" ]] && [[ ! $RUB
export RUBYOPT="$RUBYOPT -rbundler/setup -rrbs/test/setup"
export RBS_TEST_RAISE=true
export RBS_TEST_LOGLEVEL=error
export RBS_TEST_OPT="-Isig -rset -rmutex_m -rforwardable -ruri -rjson -ripaddr -rpathname -rtime -rtimeout -rresolv -rsocket -ropenssl -rbase64 -rzlib -rcgi -rhttp-2-next"
export RBS_TEST_OPT="-Isig -rset -rmutex_m -rforwardable -ruri -rjson -ripaddr -rpathname -rtime -rtimeout -rresolv -rsocket -ropenssl -rbase64 -rzlib -rcgi -rdigest -rhttp-2-next"
export RBS_TEST_TARGET="HTTP*"
fi