Skip to content

Commit

Permalink
Add Net::HTTP adapter with dynamic config example
Browse files Browse the repository at this point in the history
  • Loading branch information
pjambet committed May 2, 2023
1 parent 14eb794 commit 9e9dce8
Showing 1 changed file with 113 additions and 0 deletions.
113 changes: 113 additions & 0 deletions examples/net_http/07_circuit_dynamic_config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# frozen_string_literal: true

require "semian"
require "semian/net_http"
require_relative "../colors"

puts "> Starting example #{__FILE__}".blue.bold
puts
puts "> Initialize print Semian state changes".blue.bold
Semian.subscribe do |event, resource, scope, adapter|
puts "[semian] adapter=#{adapter} scope=#{scope} event=#{event} " \
"resource_name=#{resource.name} resource=#{resource}".gray
end

SEMIAN_PARAMETERS = {
circuit_breaker: true,
success_threshold: 3,
error_threshold: 1,
error_timeout: 5,
bulkhead: false,
dynamic: true,
open_circuit_server_errors: true,
}

uri = URI("http://example.com:80")

puts "> Configure Circuit breaker for Net::HTTP".blue.bold
Semian::NetHTTP.semian_configuration = proc do |host, port|
puts "[semian/http] invoked config for host=#{host}(#{host.class}) port=#{port}(#{port.class})".gray

if host == "example.com"
puts " set resource name example_com".gray
sub_resource_name = Thread.current[:current_semian_sub_resource_name]
# We purposefully do not use the port as the resource name, so that we can
# force the circuit to open by sending a request to an invalid port, e.g. 81
SEMIAN_PARAMETERS.merge(name: "example_com_#{sub_resource_name}")
else
puts " skip semian initialization".gray
nil
end
end

puts "> Test requests".blue.bold
puts " >> 1. Request to http://example.com - success".cyan
Thread.current[:current_semian_sub_resource_name] = "sub_resource_1"
response = Net::HTTP.get_response(uri)
puts " > Response status: #{response.code}"
puts

puts " >> 2. Request to http://example.com - success".cyan
Thread.current[:current_semian_sub_resource_name] = "sub_resource_2"
response = Net::HTTP.get_response(uri)
puts " > Response status: #{response.code}"
puts

puts "> Review semian state:".blue.bold
resource1 = Semian["nethttp_example_com_sub_resource_1"]
puts "resource_name=#{resource1.name} resource=#{resource1} " \
"closed=#{resource1.closed?} open=#{resource1.open?} " \
"half_open=#{resource1.half_open?}".gray
resource2 = Semian["nethttp_example_com_sub_resource_2"]
puts "resource_name=#{resource2.name} resource=#{resource2} " \
"closed=#{resource2.closed?} open=#{resource2.open?} " \
"half_open=#{resource2.half_open?}".gray
puts

puts "> Test request errors".blue.bold
puts " >> 3. Request to http://example.com - fail".magenta
Thread.current[:current_semian_sub_resource_name] = "sub_resource_1"
begin
# We use a different port to make the connection fail
Net::HTTP.start(uri.host, 81, open_timeout: 1) do |http|
http.request_get(uri)
end
rescue => e
puts " >> Could not connect: #{e.message}".brown
puts
end

puts " >> 4. Request to http://example.com - success".cyan
Thread.current[:current_semian_sub_resource_name] = "sub_resource_2"
response = Net::HTTP.get_response(uri)
puts " > Response status: #{response.code}"
puts

puts "> Review semian state:".blue.bold
resource1 = Semian["nethttp_example_com_sub_resource_1"]
puts "resource_name=#{resource1.name} resource=#{resource1} " \
"closed=#{resource1.closed?} open=#{resource1.open?} " \
"half_open=#{resource1.half_open?}".gray
resource2 = Semian["nethttp_example_com_sub_resource_2"]
puts "resource_name=#{resource2.name} resource=#{resource2} " \
"closed=#{resource2.closed?} open=#{resource2.open?} " \
"half_open=#{resource2.half_open?}".gray
puts

puts " >> 5. Request to http://example.com - fail".magenta
begin
Thread.current[:current_semian_sub_resource_name] = "sub_resource_1"
Net::HTTP.get_response(uri)
rescue Net::CircuitOpenError => e
puts " >> Semian is open: #{e.message}".brown
puts " !!! Semian open for sub_resource_1 and no request made to example.com:80 !!!".red.bold
end
puts

puts " >> 6. Request to http://example.com - success".cyan
Thread.current[:current_semian_sub_resource_name] = "sub_resource_2"
response = Net::HTTP.get_response(uri)
puts " > Response status: #{response.code}"
puts

puts "> That's all Folks!".green

0 comments on commit 9e9dce8

Please sign in to comment.