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.
- checksums.yaml +4 -4
- data/.rubocop.yml +47 -0
- data/Gemfile +9 -8
- data/README.md +254 -55
- data/Rakefile +32 -25
- data/VERSION +1 -1
- data/assets/images/sc4ry_workflow.png +0 -0
- data/bin/console +4 -3
- data/lib/sc4ry/backends/init.rb +3 -1
- data/lib/sc4ry/backends/memory.rb +16 -18
- data/lib/sc4ry/backends/redis.rb +59 -62
- data/lib/sc4ry/circuits.rb +111 -105
- data/lib/sc4ry/config.rb +89 -81
- data/lib/sc4ry/constants.rb +50 -46
- data/lib/sc4ry/dependencies.rb +3 -3
- data/lib/sc4ry/exceptions.rb +36 -42
- data/lib/sc4ry/exporters/init.rb +3 -1
- data/lib/sc4ry/helpers.rb +29 -34
- data/lib/sc4ry/logger.rb +24 -23
- data/lib/sc4ry/notifiers/init.rb +34 -33
- data/lib/sc4ry/notifiers/mattermost.rb +37 -38
- data/lib/sc4ry/notifiers/prometheus.rb +15 -19
- data/lib/sc4ry/run_controller.rb +23 -30
- data/lib/sc4ry/store.rb +45 -39
- data/lib/sc4ry/version.rb +2 -1
- data/lib/sc4ry.rb +3 -9
- data/samples/test.rb +159 -0
- data/sc4ry.gemspec +19 -19
- metadata +23 -22
- data/ultragreen_roodi_coding_convention.yml +0 -25
data/lib/sc4ry/notifiers/init.rb
CHANGED
@@ -1,57 +1,58 @@
|
|
1
|
-
|
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
|
-
#
|
8
|
-
|
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 = {:
|
13
|
-
:
|
14
|
-
|
15
|
-
|
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
|
21
|
-
|
22
|
-
|
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
|
28
|
-
|
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
|
35
|
-
|
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
|
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
|
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
|
-
|
55
|
+
config
|
54
56
|
end
|
55
|
-
|
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
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
-
@@
|
14
|
-
|
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
|
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 = {:
|
27
|
-
if Sc4ry::Helpers
|
28
|
-
|
29
|
-
@@metric_circuit_state.set(status_map[status], labels: {circuit: circuit.to_s })
|
30
|
-
Sc4ry::Helpers.log level: :debug,
|
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
|
-
|
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
|
data/lib/sc4ry/run_controller.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
53
|
+
rescue StandardError => e
|
55
54
|
@last_exception = e.class.to_s
|
56
|
-
if e.
|
55
|
+
if e.instance_of?(Timeout::Error)
|
57
56
|
@timeout = true
|
58
57
|
elsif @circuit[:exceptions].include? e.class
|
59
58
|
@failure = true
|
60
|
-
|
61
|
-
|
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
|
-
|
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
|
-
|
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::
|
6
|
-
#
|
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 = {:
|
16
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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)
|
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]
|
68
|
-
|
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: {}
|
78
|
-
raise Sc4ry::Exceptions::Sc4ryBackendError
|
79
|
-
|
80
|
-
|
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
|
-
|
89
|
-
|
90
|
-
|
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,
|
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
data/lib/sc4ry.rb
CHANGED
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'
|