diff --git a/examples/net_http/07_circuit_dynamic_config.rb b/examples/net_http/07_circuit_dynamic_config.rb new file mode 100644 index 00000000..feb6ca69 --- /dev/null +++ b/examples/net_http/07_circuit_dynamic_config.rb @@ -0,0 +1,103 @@ +# 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, +} + +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 == "httpbin.org" && port == 80 + puts " set resource name http_bin_80".gray + sub_resource_name = Thread.current[:current_semian_sub_resource_name] + SEMIAN_PARAMETERS.merge(name: "http_bin_80_#{sub_resource_name}") + else + puts " skip semian initialization".gray + nil + end +end + +puts "> Test requests".blue.bold +puts " >> 1. Request to http://httpbin.org/status/200 - success".cyan +Thread.current[:current_semian_sub_resource_name] = "sub_resource_1" +response = Net::HTTP.get_response("httpbin.org", "/status/200") +puts " > Response status: #{response.code}" +puts + +puts " >> 2. Request to http://httpbin.org/status/200 - success".cyan +Thread.current[:current_semian_sub_resource_name] = "sub_resource_2" +response = Net::HTTP.get_response("httpbin.org", "/status/200") +puts " > Response status: #{response.code}" +puts + +puts "> Review semian state:".blue.bold +resource1 = Semian["nethttp_http_bin_80_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_http_bin_80_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://httpbin.org/status/500 - success".cyan +Thread.current[:current_semian_sub_resource_name] = "sub_resource_1" +response = Net::HTTP.get_response("httpbin.org", "/status/500") +puts " > Response status: #{response.code}" +puts + +puts " >> 4. Request to http://httpbin.org/status/200 - success".cyan +Thread.current[:current_semian_sub_resource_name] = "sub_resource_2" +response = Net::HTTP.get_response("httpbin.org", "/status/200") +puts " > Response status: #{response.code}" +puts + +puts "> Review semian state:".blue.bold +resource1 = Semian["nethttp_http_bin_80_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_http_bin_80_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://httpbin.org/status/200 - fail".magenta +begin + Thread.current[:current_semian_sub_resource_name] = "sub_resource_1" + Net::HTTP.get_response("httpbin.org", "/status/200") +rescue Net::CircuitOpenError => e + puts " >> Semian is open: #{e.message}".brown + puts " !!! Semian open for sub_resource_1 and no request made to httpbin.org:80 !!!".red.bold +end +puts + +puts " >> 6. Request to http://httpbin.org/status/200 - success".cyan +Thread.current[:current_semian_sub_resource_name] = "sub_resource_2" +response = Net::HTTP.get_response("httpbin.org", "/status/200") +puts " > Response status: #{response.code}" +puts + +puts "> That's all Folks!".green