sc4ry 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,57 +1,58 @@
1
- Dir[File.dirname(__FILE__) + '/*.rb'].sort.each { |file| require file unless File.basename(file) == 'init.rb' }
1
+ # frozen_string_literal: true
2
+
3
+ Dir["#{File.dirname(__FILE__)}/*.rb"].sort.each { |file| require file unless File.basename(file) == 'init.rb' }
2
4
 
3
5
  # Sc4ry module
4
6
  # @note namespace
5
- module Sc4ry
6
-
7
- # Sc4ry::Notifiers module
8
- # @note namespace
9
- module Notifiers
10
-
7
+ module Sc4ry
8
+ # Sc4ry::Notifiers module
9
+ # @note namespace
10
+ module Notifiers
11
11
  # default notifiers specifications
12
- DEFAULT_NOTIFIERS = {:prometheus => {:class => Sc4ry::Notifiers::Prometheus, :config => {:url => 'http://localhost:9091'}},
13
- :mattermost => {:class => Sc4ry::Notifiers::Mattermost, :config => {:url => 'http://localhost:9999', :token => "<CHANGE_ME>"}}
14
- }
15
- @@notifiers_list = DEFAULT_NOTIFIERS.dup
16
-
12
+ DEFAULT_NOTIFIERS = { prometheus: { class: Sc4ry::Notifiers::Prometheus, config: { url: 'http://localhost:9091' } },
13
+ mattermost: { class: Sc4ry::Notifiers::Mattermost, config: { url: 'http://localhost:9999', token: '<CHANGE_ME>' } } }
14
+ @@notifiers_list = DEFAULT_NOTIFIERS.dup
15
+
17
16
  # class method how display a specific notifier config
18
17
  # @param notifier [Symbol] a notifier name
19
- # @return [Hash] the config
20
- def Notifiers.display_config(notifier: )
21
- raise Sc4ry::Exceptions::Sc4ryNotifierError, "Notifier #{notifier} not found" unless @@notifiers_list.include? notifier
22
- return @@notifiers_list[notifier][:config]
18
+ # @return [Hash] the config
19
+ def self.display_config(notifier:)
20
+ unless @@notifiers_list.include? notifier
21
+ raise Sc4ry::Exceptions::Sc4ryNotifierError,
22
+ "Notifier #{notifier} not found"
23
+ end
24
+
25
+ @@notifiers_list[notifier][:config]
23
26
  end
24
27
 
25
28
  # class method how return the list of known notifiers
26
29
  # @return [Array] a list of [Symbol] notifiers name
27
- def Notifiers.list
28
- return @@notifiers_list.keys
30
+ def self.list
31
+ @@notifiers_list.keys
29
32
  end
30
33
 
31
34
  # class method how return a specific notifier by name
32
35
  # @param name [Symbol] a notifier name
33
- # @return [Hash] the notifier structure
34
- def Notifiers.get(name: )
35
- return @@notifiers_list[name]
36
+ # @return [Hash] the notifier structure
37
+ def self.get(name:)
38
+ @@notifiers_list[name]
36
39
  end
37
40
 
38
- # class method how register a specific notifier
41
+ # class method how register a specific notifier
39
42
  # @param name [Symbol] a notifier name
40
- # @param definition [Hash] a notifier definition
41
- # @return [Hash] the notifier structure
42
- def Notifiers.register(name: , definition: )
43
+ # @param definition [Hash] a notifier definition
44
+ # @return [Hash] the notifier structure
45
+ def self.register(name:, definition:)
43
46
  @@notifiers_list[name] = definition
44
47
  end
45
48
 
46
-
47
- # class method how configure a specific notifier
49
+ # class method how configure a specific notifier
48
50
  # @param name [Symbol] a notifier name
49
- # @param config [Hash] a notifier config
50
- # @return [Hash] the notifier structure
51
- def Notifiers.config(name:, config: )
51
+ # @param config [Hash] a notifier config
52
+ # @return [Hash] the notifier structure
53
+ def self.config(name:, config:)
52
54
  @@notifiers_list[name][:config] = config
53
- return config
55
+ config
54
56
  end
55
- end
57
+ end
56
58
  end
57
-
@@ -1,43 +1,42 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Sc4ry module
2
- # @note namespace
4
+ # @note namespace
3
5
  module Sc4ry
4
- # Sc4ry::Notifiers module
5
- # @note namespace
6
- module Notifiers
7
-
8
- # Mattermost Notifier class
9
- class Mattermost
10
-
11
- # send metrics to Prometheus PushGateway
12
- # @return [Bool]
13
- def Mattermost.notify(options = {})
14
- config = Sc4ry::Notifiers.get(name: :mattermost)[:config]
15
- status = options[:config][:status][:general]
16
- circuit = options[:circuit]
17
- status_map = {:open => 0, :half_open => 1, :closed => 2}
18
- begin
19
- uri = URI.parse("#{config[:url]}/hooks/#{config[:token]}")
20
- message = "notifying for circuit #{circuit.to_s}, state : #{status.to_s}."
21
- if Sc4ry::Helpers::verify_service url: config[:url] then
22
- request = ::Net::HTTP::Post.new(uri)
23
- request.content_type = "application/json"
24
- req_options = {
25
- use_ssl: uri.scheme == "https",
26
- }
27
- payload = { "text" => "message : #{message } from #{Socket.gethostname}", "username" => "Sc4ry" }
28
- Sc4ry::Helpers.log level: :debug, message: "Mattermost Notifying : #{message}"
29
- request.body = ::JSON.dump(payload)
30
- response = ::Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
31
- http.request(request)
32
- end
33
-
34
- else
35
- Sc4ry::Helpers.log level: :warn, message: "Mattermost Notifier : can't notify Mattermost not reachable."
36
- end
37
- rescue URI::InvalidURIError
38
- Sc4ry::Helpers.log level: :warn, message: "Mattermost Notifier : URL malformed"
39
- end
6
+ # Sc4ry::Notifiers module
7
+ # @note namespace
8
+ module Notifiers
9
+ # Mattermost Notifier class
10
+ class Mattermost
11
+ # send metrics to Prometheus PushGateway
12
+ # @return [Bool]
13
+ def self.notify(options = {})
14
+ config = Sc4ry::Notifiers.get(name: :mattermost)[:config]
15
+ status = options[:config][:status][:general]
16
+ circuit = options[:circuit]
17
+ begin
18
+ uri = URI.parse("#{config[:url]}/hooks/#{config[:token]}")
19
+ message = "notifying for circuit #{circuit}, state : #{status}."
20
+ if Sc4ry::Helpers.verify_service url: config[:url]
21
+ request = ::Net::HTTP::Post.new(uri)
22
+ request.content_type = 'application/json'
23
+ req_options = {
24
+ use_ssl: uri.scheme == 'https'
25
+ }
26
+ payload = { 'text' => "message : #{message} from #{Socket.gethostname}", 'username' => 'Sc4ry' }
27
+ Sc4ry::Helpers.log level: :debug, message: "Mattermost Notifying : #{message}"
28
+ request.body = ::JSON.dump(payload)
29
+ ::Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
30
+ http.request(request)
40
31
  end
32
+
33
+ else
34
+ Sc4ry::Helpers.log level: :warn, message: "Mattermost Notifier : can't notify Mattermost not reachable."
35
+ end
36
+ rescue URI::InvalidURIError
37
+ Sc4ry::Helpers.log level: :warn, message: 'Mattermost Notifier : URL malformed'
41
38
  end
39
+ end
42
40
  end
43
- end
41
+ end
42
+ end
@@ -1,43 +1,39 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Sc4ry module
2
4
  # @note namespace
3
5
  module Sc4ry
4
-
5
6
  # Sc4ry::Notifiers module
6
7
  # @note namespace
7
8
  module Notifiers
8
-
9
-
10
9
  # Prometheus notifier class
11
10
  class Prometheus
12
-
13
- @@registry = ::Prometheus::Client::Registry::new
14
- @@metric_circuit_state = ::Prometheus::Client::Gauge.new(:cuircuit_state, docstring: 'Sc4ry metric : state of a circuit', labels: [:circuit])
11
+ @@registry = ::Prometheus::Client::Registry.new
12
+ @@metric_circuit_state = ::Prometheus::Client::Gauge.new(:cuircuit_state,
13
+ docstring: 'Sc4ry metric : state of a circuit',
14
+ labels: [:circuit])
15
15
 
16
16
  @@registry.register(@@metric_circuit_state)
17
17
 
18
-
19
-
20
18
  # send metrics to Prometheus PushGateway
21
19
  # @return [Bool]
22
- def Prometheus.notify(options = {})
20
+ def self.notify(options = {})
23
21
  @config = Sc4ry::Notifiers.get(name: :prometheus)[:config]
24
22
  status = options[:config][:status][:general]
25
23
  circuit = options[:circuit]
26
- status_map = {:open => 0, :half_open => 1, :closed => 2}
27
- if Sc4ry::Helpers::verify_service url: @config[:url] then
28
-
29
- @@metric_circuit_state.set(status_map[status], labels: {circuit: circuit.to_s })
30
- Sc4ry::Helpers.log level: :debug, message: "Prometheus Notifier : notifying for circuit #{circuit.to_s}, state : #{status.to_s}."
24
+ status_map = { open: 0, half_open: 1, closed: 2 }
25
+ if Sc4ry::Helpers.verify_service url: @config[:url]
26
+
27
+ @@metric_circuit_state.set(status_map[status], labels: { circuit: circuit.to_s })
28
+ Sc4ry::Helpers.log level: :debug,
29
+ message: "Prometheus Notifier : notifying for circuit #{circuit}, state : #{status}."
31
30
 
32
- return ::Prometheus::Client::Push.new(job: "Sc4ry", instance: Socket.gethostname, gateway: @config[:url]).add(@@registry)
31
+ ::Prometheus::Client::Push.new(job: 'Sc4ry', instance: Socket.gethostname,
32
+ gateway: @config[:url]).add(@@registry)
33
33
  else
34
34
  Sc4ry::Helpers.log level: :warn, message: "Prometheus Notifier : can't notify Push Gateway not reachable."
35
35
  end
36
36
  end
37
37
  end
38
-
39
-
40
-
41
38
  end
42
-
43
39
  end
@@ -1,16 +1,15 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  # Sc4ry module
3
- # @note namespace
4
+ # @note namespace
4
5
  module Sc4ry
5
-
6
6
  # class Facility to run and update values/status for a circuit Proc
7
7
  class RunController
8
-
9
8
  # return the execution time of the proc
10
9
  attr_reader :execution_time
11
10
 
12
11
  # constructor
13
- # @param [Hash] circuit the data of the circuit
12
+ # @param [Hash] circuit the data of the circuit
14
13
  def initialize(circuit = {})
15
14
  @circuit = circuit
16
15
  @execution_time = 0
@@ -22,59 +21,53 @@ module Sc4ry
22
21
  # return if the Proc failed on a covered exception by this circuit
23
22
  # @return [Boolean]
24
23
  def failed?
25
- return @failure
26
- end
24
+ @failure
25
+ end
27
26
 
28
27
  # return if the Proc overtime the specified time of the circuit
29
28
  # @return [Boolean]
30
- def overtimed?
31
- return @overtime
29
+ def overtimed?
30
+ @overtime
32
31
  end
33
32
 
34
33
  # return if the Proc timeout the timeout defined value of the circuit, if timeout is active
35
34
  # @return [Boolean]
36
- def timeout?
37
- return @timeout
35
+ def timeout?
36
+ @timeout
38
37
  end
39
38
 
40
39
  # run and update values for the bloc given by keyword
41
40
  # @param [Proc] block a block to run and calculate
42
41
  # @return [Hash] a result Hash
43
- def run(block: )
42
+ def run(block:)
44
43
  start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
45
- begin
44
+ begin
46
45
  if @circuit[:timeout] == true
47
- Timeout::timeout(@circuit[:timeout_value]) do
46
+ Timeout.timeout(@circuit[:timeout_value]) do
48
47
  block.call
49
48
  end
50
49
  @timeout = false
51
50
  else
52
51
  block.call
53
52
  end
54
- rescue Exception => e
53
+ rescue StandardError => e
55
54
  @last_exception = e.class.to_s
56
- if e.class == Timeout::Error then
55
+ if e.instance_of?(Timeout::Error)
57
56
  @timeout = true
58
57
  elsif @circuit[:exceptions].include? e.class
59
58
  @failure = true
60
- else
61
- if @circuit[:forward_unknown_exceptions] then
59
+ elsif @circuit[:forward_unknown_exceptions]
60
+ raise e.class, "Sc4ry forward: #{e.message}"
61
+ else
62
+ Sc4ry::Helpers.log level: :debug, message: "skipped : #{@last_exception}"
62
63
 
63
- raise e.class, "Sc4ry forward: #{e.message}"
64
- else
65
- Sc4ry::Helpers.log level: :debug, message: "skipped : #{@last_exception}"
66
- end
67
-
68
- end
64
+ end
69
65
  end
70
66
  @end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
71
67
  @execution_time = @end_time - start_time
72
- @overtime = @execution_time > @circuit[:max_time]
73
- return {failure: @failure, overtime: @overtime, timeout: @timeout, execution_time: @execution_time, end_time: @end_time, last_exception: @last_exception}
74
-
68
+ @overtime = @execution_time > @circuit[:max_time]
69
+ { failure: @failure, overtime: @overtime, timeout: @timeout, execution_time: @execution_time,
70
+ end_time: @end_time, last_exception: @last_exception }
75
71
  end
76
-
77
-
78
-
79
72
  end
80
- end
73
+ end
data/lib/sc4ry/store.rb CHANGED
@@ -1,29 +1,29 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Sc4ry module
2
4
  # @note namespace
3
5
  module Sc4ry
4
-
5
- # Sc4ry::Store class
6
- # Store Class Provider/manager singleton Forwarder on {Sc4ry::Backends::Memory} or {Sc4ry::Backends::Redis}
7
- # @note must be accessed by {Sc4ry::Circuits.store}
6
+ # Sc4ry::Store class
7
+ # Store Class Provider/manager singleton Forwarder on {Sc4ry::Backends::Memory} or {Sc4ry::Backends::Redis}
8
+ # @note must be accessed by {Sc4ry::Circuits.store}
8
9
  class Store
9
-
10
10
  @@current = :memory
11
11
 
12
12
  extend Forwardable
13
13
  include Singleton
14
14
 
15
- @@backends = {:memory => {:class => Sc4ry::Backends::Memory, config: {}},
16
- :redis => {:class => Sc4ry::Backends::Redis, :config => {:host => 'localhost', :port => 6379, :db => 10 }}}
15
+ @@backends = { memory: { class: Sc4ry::Backends::Memory, config: {} },
16
+ redis: { class: Sc4ry::Backends::Redis, config: { host: 'localhost', port: 6379, db: 1 } } }
17
17
 
18
18
  # accessor on current backend (default :memory)
19
19
  attr_reader :be
20
-
20
+
21
21
  def_delegators :@be, :put, :get, :flush, :exist?, :del, :list
22
22
 
23
23
  # constructor pointing on :memory backend
24
24
  def initialize
25
- change_backend name: @@current
26
- end
25
+ change_backend name: @@current
26
+ end
27
27
 
28
28
  # return the current backend
29
29
  # @return [Object] in {Sc4ry::Backends::Memory} or {Sc4ry::Backends::Redis}
@@ -31,75 +31,81 @@ module Sc4ry
31
31
  # include Sc4ry
32
32
  # puts Circuits.store.current
33
33
  def current
34
- return @@current
34
+ @@current
35
35
  end
36
36
 
37
37
  # return the config of a specific backend
38
- # @param [Symbol] backend the name the backend
39
- # @return [Hash] the config of the backend
38
+ # @param [Symbol] backend the name the backend
39
+ # @return [Hash] the config of the backend
40
40
  # @raise Sc4ry::Exceptions::Sc4ryBackendError if backend is not found
41
41
  # @example usage
42
42
  # include Sc4ry
43
43
  # puts Circuits.store.get_config backend: :redis
44
- def get_config(backend: )
44
+ def get_config(backend:)
45
45
  raise Sc4ry::Exceptions::Sc4ryBackendError, "backend #{backend} not found" unless @@backends.include? backend
46
- return @@backends[backend][:config]
46
+
47
+ @@backends[backend][:config]
47
48
  end
48
49
 
49
- # list backend available
50
+ # list backend available
50
51
  # @return [Array] of Symbol the list of backend name
51
52
  # @example usage
52
53
  # include Sc4ry
53
54
  # puts Circuits.store.list_backend
54
55
  def list_backend
55
- return @@backends.keys
56
+ @@backends.keys
56
57
  end
57
58
 
58
- # change the current backend
59
- # @note if changing form :memory to :redis => all values and result are lost and circuits will be lost
60
- # @note if changing to :redis, get all the define circuits with values and status (ideal) for distributed worker/instance/runner/services
59
+ # change the current backend
60
+ # @note if changing form :memory to :redis => all values and result are lost and circuits will be lost
61
+ # @note if changing to :redis, get all the define circuits with values and status (ideal)
62
+ # @note for distributed worker/instance/runner/services
61
63
  # @param [Symbol] name the name of the target backend
62
64
  # @return [Symbol] the name of the new current backend
63
65
  # @raise Sc4ry::Exceptions::Sc4ryBackendError if backend is not found
64
- def change_backend(name: )
66
+ def change_backend(name:)
65
67
  raise Sc4ry::Exceptions::Sc4ryBackendError, "backend #{name} not found" unless @@backends.include? name
68
+
66
69
  @@current = name
67
- @be = @@backends[@@current][:class]::new(@@backends[@@current][:config])
68
- return name
70
+ @be = @@backends[@@current][:class].new(@@backends[@@current][:config])
71
+ name
69
72
  end
70
73
 
71
- # register a new backend
74
+ # register a new backend
72
75
  # @param [Symbol] name the name of the backend
73
76
  # @param [Hash] config the config for this backend
74
- # @param [Class] backend_class the class name of the new backend
77
+ # @param [Class] backend_class the class name of the new backend
75
78
  # @raise Sc4ry::Exceptions::Sc4ryBackendError if backend already exist
76
- # @return [Symbol] the name of the backend
77
- def register_backend(name:, config: {}, backend_class:)
78
- raise Sc4ry::Exceptions::Sc4ryBackendError , "backend #{name} already exist" if @@backends.include? name
79
- @@backends[name] = {config: config, class: backend_class}
80
- return name
79
+ # @return [Symbol] the name of the backend
80
+ def register_backend(name:, backend_class:, config: {})
81
+ raise Sc4ry::Exceptions::Sc4ryBackendError, "backend #{name} already exist" if @@backends.include? name
82
+
83
+ @@backends[name] = { config: config, class: backend_class }
84
+ name
81
85
  end
82
86
 
83
87
  # delete the specified backend reference
84
88
  # @param [Symbol] name the name of the target backend
85
89
  # @raise Sc4ry::Exceptions::Sc4ryBackendError if backend is not found, or name == :memory or :redis
86
90
  # @return [Boolean]
87
- def delete_backend(name: )
88
- raise Sc4ry::Exceptions::Sc4ryBackendError , "Delete forbidden for backend in [:redis,:memory]" if [:memory,:redis].include? name
89
- raise Sc4ry::Exceptions::Sc4ryBackendError , "backend #{name} not found" unless @@backends.include? name
90
- return @@backends.delete(name)
91
+ def delete_backend(name:)
92
+ forbidden_mes = 'Delete forbidden for backend in [:redis,:memory]'
93
+ notfound_mes = "backend #{name} not found"
94
+ raise Sc4ry::Exceptions::Sc4ryBackendError, forbidden_mes if %i[memory redis].include? name
95
+ raise Sc4ry::Exceptions::Sc4ryBackendError, notfound_mes unless @@backends.include? name
96
+
97
+ @@backends.delete(name)
91
98
  end
92
-
99
+
93
100
  # change the specified backend config
94
101
  # @param [Symbol] name the name of the target backend
95
102
  # @param [Hash] config the config of the specified backend
96
103
  # @raise Sc4ry::Exceptions::Sc4ryBackendError if backend is not found, or name == :memory
97
104
  def config_backend(name:, config:)
98
105
  raise Sc4ry::Exceptions::Sc4ryBackendError, "backend #{name} not found" unless @@backends.include? name
99
- raise Sc4ry::Exceptions::Sc4ryBackendError, "backend :memory not need config" if name == :memory
106
+ raise Sc4ry::Exceptions::Sc4ryBackendError, 'backend :memory not need config' if name == :memory
107
+
100
108
  @@backends[name][:config] = config
101
109
  end
102
-
103
-
104
110
  end
105
- end
111
+ end
data/lib/sc4ry/version.rb CHANGED
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'version'
2
4
 
3
5
  # Sc4ry module
4
6
  # @note namespace
5
7
  module Sc4ry
6
-
7
8
  # the version of Sc4ry
8
9
  VERSION = Version.current
9
10
  end
data/lib/sc4ry.rb CHANGED
@@ -1,10 +1,4 @@
1
- require "sc4ry/version"
2
- require "sc4ry/dependencies"
3
-
4
-
5
-
6
-
7
-
8
-
9
-
1
+ # frozen_string_literal: true
10
2
 
3
+ require 'sc4ry/version'
4
+ require 'sc4ry/dependencies'
data/samples/test.rb ADDED
@@ -0,0 +1,159 @@
1
+ require 'rubygems'
2
+ require 'sc4ry'
3
+
4
+ include Sc4ry
5
+
6
+ # display of default Sc4ry config
7
+ puts '1.1/ CONFIG : Initial default config'
8
+ Circuits.default_config.each do |item, value|
9
+ puts " * #{item} : #{value}"
10
+ end
11
+ puts ''
12
+
13
+ # testing the two ways to configure Sc4ry default config
14
+ puts '1.2/ CONFIG : modifying default config activate timout and set max_time to 12'
15
+ Circuits.merge_default_config diff: { timeout: true }
16
+ Circuits.configure do |spec|
17
+ spec.max_time = 12
18
+ end
19
+ puts ''
20
+
21
+ # display default config, must be override with a nested hash by calling default_config= method
22
+ puts '1.3/ CONFIG : Default config updated:'
23
+ Circuits.default_config.each do |item, value|
24
+ puts " * #{item} : #{value}"
25
+ end
26
+ puts ''
27
+
28
+ # display current data Store
29
+ print '2.1/ STORE : Current datastore backend : '
30
+ puts Circuits.store.current
31
+ puts ''
32
+
33
+ # display available backend
34
+ puts '2.2/ STORE : List of existing backends : '
35
+ Circuits.store.list_backend.each do |backend|
36
+ puts " - #{backend}"
37
+ end
38
+ puts ''
39
+
40
+ # display Redis backend config in store before change
41
+ puts '2.3/ STORE : display default config of redis backend'
42
+ Circuits.store.get_config(backend: :redis).each do |item, value|
43
+ puts " * #{item} : #{value}"
44
+ end
45
+ puts ''
46
+
47
+ # reconfigure a backend
48
+ puts '2.4/ STORE : reconfigure Redis backend'
49
+ Circuits.store.config_backend name: :redis, config: { host: 'localhost', port: 6379, db: 10 }
50
+ puts
51
+
52
+ # display after
53
+ puts '2.5/ STORE : display altered config of redis backend'
54
+ Circuits.store.get_config(backend: :redis).each do |item, value|
55
+ puts " * #{item} : #{value}"
56
+ end
57
+ puts ''
58
+
59
+ # change backend
60
+
61
+ puts '2.6/ STORE : change to redis backend (NEED a Redis installed) '
62
+ puts ' $ docker pull redis:latest'
63
+ puts ' $ docker run --rm -d -p 6379:6379/tcp redis:latest'
64
+ Circuits.store.change_backend name: :redis
65
+ puts ''
66
+
67
+ puts '2.7/ STORE : flush redis backend, just for test, and for idempotency (NEED a Redis installed) '
68
+ Circuits.store.flush
69
+ puts ''
70
+
71
+ # defining a circuit, config must be empty or override from default
72
+ puts '3.1/ CIRCUIT : registering a circuit by merge :'
73
+ Circuits.register circuit: :test, config: { notifiers: %i[prometheus mattermost], exceptions: [Errno::ECONNREFUSED, URI::InvalidURIError] }
74
+ puts ''
75
+
76
+ puts '3.2/ CIRCUIT : registering a circuit by block :'
77
+ Circuits.register circuit: :test2 do |spec|
78
+ spec.exceptions = [Errno::ECONNREFUSED]
79
+ end
80
+ puts ''
81
+
82
+ puts '3.3/ CIRCUIT : registering a circuit by default :'
83
+ Circuits.register circuit: :test3
84
+ puts ''
85
+
86
+ puts '3.4/ CIRCUITS : Circuits list'
87
+ Circuits.list.each do |circuit|
88
+ puts " * #{circuit}"
89
+ end
90
+ puts ''
91
+
92
+ puts '3.5/ CIRCUIT : display a circuit config :test3 :'
93
+ Circuits.get(circuit: :test3).each do |item, value|
94
+ puts " * #{item} : #{value}"
95
+ end
96
+ puts ''
97
+
98
+ puts '3.6/ CIRCUIT : update config of :test3 => :raise_on_opening == true :'
99
+ Circuits.update_config circuit: :test3, config: { raise_on_opening: true }
100
+ puts ''
101
+
102
+ puts '3.7/ CIRCUIT : display a circuit config :test3 after change :'
103
+ Circuits.get(circuit: :test3).each do |item, value|
104
+ puts " * #{item} : #{value}"
105
+ end
106
+ puts ''
107
+
108
+ puts '3.8/ unregister a circuit : :test2 :'
109
+ Circuits.unregister circuit: :test2
110
+ puts ''
111
+
112
+ puts '3.9/ CIRCUITS : Circuits list after unregister'
113
+ Circuits.list.each do |circuit|
114
+ puts " * #{circuit}"
115
+ end
116
+ puts ''
117
+
118
+ # Config an alternate logger
119
+
120
+ puts '4.1/ LOGGER : register a logger on file '
121
+ Circuits.loggers.register name: :perso, instance: ::Logger.new('/tmp/logfile.log')
122
+ puts ''
123
+
124
+ puts '4.2/ LOGGER : get the list of available loggers'
125
+ Circuits.loggers.list_available.each do |logger|
126
+ puts " * #{logger}"
127
+ end
128
+ puts ''
129
+
130
+ puts '4.3/ LOGGER : change logger to :perso'
131
+ Circuits.loggers.current = :perso
132
+ puts ''
133
+
134
+ # sample Mattermost notification
135
+ puts '5/ set notifier mattermost on dummy url, change with your slack or mattermost server'
136
+ Sc4ry::Notifiers.config name: :mattermost, config: { url: 'https://mattermost.mycorp.com', token: '<TOKEN>' }
137
+ puts ''
138
+
139
+ # sample loop
140
+ puts '6/ running circuits test, please wait ... (see /tmp/logfile.log for result)'
141
+ puts ' check endoint status for different result, you cloud use http://github.com/Ultragreen/MockWS for testing endpoint, on an other tty'
142
+ puts ' $ git clone https://github.com/Ultragreen/MockWS.git'
143
+ puts ' $ cd MockWS'
144
+ puts ' $ rackup'
145
+ begin
146
+ 10.times do
147
+ sleep 1
148
+ Circuits.run circuit: :test do
149
+ # for the test choose or build an endpoint you must shutdown
150
+ puts RestClient.get('http://localhost:9292/test2/data')
151
+ end
152
+ end
153
+ rescue Interrupt
154
+ puts 'Interrputed'
155
+ ensure
156
+ Circuits.store.flush
157
+ end
158
+
159
+ puts 'end'