Class: Sc4ry::Circuits
- Inherits:
-
Object
- Object
- Sc4ry::Circuits
- Includes:
- Constants, Exceptions
- Defined in:
- lib/sc4ry/circuits.rb
Overview
Circuits and default configuration management class
Constant Summary collapse
- @@circuits_store =
Sc4ry::Store.instance
- @@circuits_notifiers =
Sc4ry::Notifiers
- @@circuits_loggers =
Sc4ry::Loggers
- @@config =
DEFAULT_CONFIG
Constants included from Constants
Sc4ry::Constants::CURRENT_NOTIFIERS, Sc4ry::Constants::DEFAULT_CONFIG, Sc4ry::Constants::DEFAULT_CONFIG_FORMATS
forwarders collapse
-
.loggers ⇒ Sc4ry::Store
Class method how forward the Logger manager class factory/manager.
-
.notifiers ⇒ Sc4ry::Notifiers
Class method how forward the Notifiers class factory/manager.
-
.store ⇒ Sc4ry::Store
Class method how forward a Store manager class singleton.
Default Sc4ry configuration management collapse
-
.configure {|Sc4ry::Config::ConfigMapper| ... } ⇒ Object
class method for specifiying config by block.
-
.default_config ⇒ Hash
Class method how return de default Sc4ry config.
-
.default_config=(config) ⇒ Object
deprecated
Deprecated.
use Circuits.merge_default_config instead
-
.merge_default_config(diff:) ⇒ Object
class method how merge a differential hash to default config.
Circuits management collapse
-
.flush ⇒ true, false
class method how flush all circuits in current store.
-
.get(circuit:) ⇒ Hash
class method for get a specific circuit by circuit name.
-
.list ⇒ Array
class method how list all circuits in current store.
-
.register(circuit:, config: {}) {|Sc4ry::Config::ConfigMapper| ... } ⇒ Hash
class method for registering a new circuit, cloud work with a block.
-
.run(circuit: nil) {|Proc| ... } ⇒ Hash
class method for running circuit, need a block.
-
.status(circuit:) ⇒ Symbol
class method for get the status of a specific circuit by circuit name.
-
.unregister(circuit:) ⇒ true, false
class method for unregistering a circuit.
-
.update_config(circuit:, config: { forward_unknown_exceptions: false }) ⇒ Hash
class method for update the config of a specific circuit by circuit name.
Class Method Summary collapse
-
.control(circuit:, values:) ⇒ Boolean
the private class method to control circuits running status.
Class Method Details
.configure {|Sc4ry::Config::ConfigMapper| ... } ⇒ Object
class method for specifiying config by block
64 65 66 67 68 69 70 |
# File 'lib/sc4ry/circuits.rb', line 64 def self.configure mapper = Sc4ry::Config::ConfigMapper.new(definition: @@config.dup) yield(mapper) validator = Sc4ry::Config::Validator.new(definition: mapper.config, from: @@config) validator.validate! @@config = validator.result end |
.control(circuit:, values:) ⇒ Boolean
the private class method to control circuits running status
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 |
# File 'lib/sc4ry/circuits.rb', line 238 def self.control(circuit:, values:) data = @@circuits_store.get key: circuit unless data.include? :status data[:status] = { general: :closed, failure_count: 0, overtime_count: 0, timeout_count: 0 } end data[:values] = [] unless data.include? :values level = [data[:max_failure_count].to_i, data[:max_timeout_count].to_i, data[:max_overtime_count].to_i].max data[:values].shift if data[:values].size > level data[:values].push values worst_status = [] %w[failure overtime timeout].each do |control| if values[control.to_sym] == true data[:status]["#{control}_count".to_sym] += 1 else data[:status]["#{control}_count".to_sym] = 0 end case data[:status]["#{control}_count".to_sym] when 0 worst_status.push :closed when 1..data["max_#{control}_count".to_sym] worst_status.push :half_open else worst_status.push :open end end save = data[:status][:general] %i[closed half_open open].each do |status| data[:status][:general] = status if worst_status.include? status end if save != data[:status][:general] raise CircuitBreaked if data[:status][:general] == :open && data[:raise_on_opening] if data[:status][:general] == :open Sc4ry::Helpers.log level: :error, message: "Circuit #{circuit} : breacking ! " end if data[:status][:general] == :closed Sc4ry::Helpers.log level: :info, message: "Circuit #{circuit} : is now closed" end Sc4ry::Helpers.notify circuit: circuit, config: data end @@circuits_store.put key: circuit, value: data end |
.default_config ⇒ Hash
Class method how return de default Sc4ry config
42 43 44 |
# File 'lib/sc4ry/circuits.rb', line 42 def self.default_config @@config end |
.default_config=(config) ⇒ Object
use merge_default_config instead
old default config setter
75 76 77 78 79 80 |
# File 'lib/sc4ry/circuits.rb', line 75 def self.default_config=(config) warning_mess = 'DEPRECATED: Circuits.default_config= use Circuits.merge_default_config add: {<config_hash>}' Sc4ry::Helpers.log level: :warn, message: warning_mess Circuits.merge_default_config(diff: config) end |
.flush ⇒ true, false
class method how flush all circuits in current store
136 137 138 |
# File 'lib/sc4ry/circuits.rb', line 136 def self.flush @@circuits_store.flush end |
.get(circuit:) ⇒ Hash
class method for get a specific circuit by circuit name
161 162 163 |
# File 'lib/sc4ry/circuits.rb', line 161 def self.get(circuit:) @@circuits_store.get key: circuit end |
.list ⇒ Array
class method how list all circuits in current store
127 128 129 |
# File 'lib/sc4ry/circuits.rb', line 127 def self.list @@circuits_store.list end |
.loggers ⇒ Sc4ry::Store
Class method how forward the Logger manager class factory/manager
32 33 34 |
# File 'lib/sc4ry/circuits.rb', line 32 def self.loggers @@circuits_loggers end |
.merge_default_config(diff:) ⇒ Object
class method how merge a differential hash to default config
51 52 53 54 55 |
# File 'lib/sc4ry/circuits.rb', line 51 def self.merge_default_config(diff:) validator = Sc4ry::Config::Validator.new(definition: diff, from: @@config) validator.validate! @@config = validator.result end |
.notifiers ⇒ Sc4ry::Notifiers
Class method how forward the Notifiers class factory/manager
20 21 22 |
# File 'lib/sc4ry/circuits.rb', line 20 def self.notifiers @@circuits_notifiers end |
.register(circuit:, config: {}) {|Sc4ry::Config::ConfigMapper| ... } ⇒ Hash
class method for registering a new circuit, cloud work with a block
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/sc4ry/circuits.rb', line 101 def self.register(circuit:, config: {}) if !config.empty? && block_given? raise Sc4ryGenericError, 'config: keyword must not be defined when block is given' end if block_given? mapper = Sc4ry::Config::ConfigMapper.new(definition: @@config.dup) yield(mapper) validator = Sc4ry::Config::Validator.new(definition: mapper.config, from: @@config.dup) else validator = Sc4ry::Config::Validator.new(definition: config, from: @@config.dup) end validator.validate! Sc4ry::Helpers.log level: :debug, message: "Circuit #{circuit} : registered" raise Sc4ryGenericError, "Circuit: #{circuit} already exist in store" if @@circuits_store.exist? key: circuit @@circuits_store.put key: circuit, value: validator.result validator.result end |
.run(circuit: nil) {|Proc| ... } ⇒ Hash
class method for running circuit, need a block
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/sc4ry/circuits.rb', line 209 def self.run(circuit: nil, &block) circuits_list = Circuits.list raise Sc4ryGenericError, 'No circuit block given' unless block_given? raise Sc4ryGenericError, 'No circuits defined' if circuits_list.empty? circuit_name = circuit || circuits_list.first raise Sc4ryGenericError, "Circuit #{circuit_name} not found" unless circuits_list.include? circuit_name circuit_to_run = Circuits.get circuit: circuit_name skip = false if circuit_to_run.include?(:status) && (circuit_to_run[:status][:general] == :open) @now = Process.clock_gettime(Process::CLOCK_MONOTONIC) skip = true if (@now - circuit_to_run[:values].last[:end_time]) < circuit_to_run[:check_delay] end unless skip controller = Sc4ry::RunController.new(circuit_to_run) Circuits.control circuit: circuit_name, values: controller.run(block: block) end result = @@circuits_store.get key: circuit_name Sc4ry::Helpers.log level: :debug, message: "Circuit #{circuit_name} : status #{result[:status]}" result end |
.status(circuit:) ⇒ Symbol
class method for get the status of a specific circuit by circuit name
189 190 191 192 |
# File 'lib/sc4ry/circuits.rb', line 189 def self.status(circuit:) data = @@circuits_store.get key: circuit data.include?(:status) ? data[:status][:general] : :never_run end |
.store ⇒ Sc4ry::Store
Class method how forward a Store manager class singleton
26 27 28 |
# File 'lib/sc4ry/circuits.rb', line 26 def self.store @@circuits_store end |
.unregister(circuit:) ⇒ true, false
class method for unregistering a circuit
147 148 149 150 151 152 153 |
# File 'lib/sc4ry/circuits.rb', line 147 def self.unregister(circuit:) raise Sc4ryGenericError, "Circuit #{circuit} not found" unless Circuits.list.include? circuit @@circuits_store.del key: circuit Sc4ry::Helpers.log level: :debug, message: "Circuit #{circuit} : unregistered" true end |
.update_config(circuit:, config: { forward_unknown_exceptions: false }) ⇒ Hash
: important updating config will reset status and values !
class method for update the config of a specific circuit by circuit name
173 174 175 176 177 178 179 180 181 |
# File 'lib/sc4ry/circuits.rb', line 173 def self.update_config(circuit:, config: { forward_unknown_exceptions: false }) raise Sc4ryGenericError, "Circuit #{circuit} not found" unless Circuits.list.include? circuit save = @@circuits_store.get key: circuit save.delete_if { |key, _val| %i[status values].include? key } Circuits.unregister(circuit: circuit) save.merge! config Circuits.register circuit: circuit, config: save end |