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/backends/redis.rb
CHANGED
@@ -1,66 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Sc4ry
|
2
|
-
|
3
|
-
|
4
|
-
|
4
|
+
module Backends
|
5
|
+
# Redis backend definition
|
6
|
+
class Redis
|
7
|
+
# Constructor
|
8
|
+
# @param [Hash] config Config map
|
9
|
+
# @return [Sc4ry::Backends::Redis] a Redis backend
|
10
|
+
def initialize(config)
|
11
|
+
@auth = config.slice(:auth)[:auth]
|
12
|
+
@config = config.slice(:host, :port, :db)
|
13
|
+
@be = ::Redis.new @config
|
14
|
+
@be.auth(@auth) if @auth
|
15
|
+
end
|
16
|
+
|
17
|
+
# return the list of find records in backend for a specific pattern
|
18
|
+
# @return [Array] list of record (for all hostname if hostname is specified)
|
19
|
+
def list
|
20
|
+
@be.keys('*').map(&:to_sym)
|
21
|
+
end
|
22
|
+
|
23
|
+
# return value of queried record
|
24
|
+
# @param key [Symbol] the name of the record
|
25
|
+
# @return [String] content value of record
|
26
|
+
def get(key:)
|
27
|
+
res = YAML.load(@be.get(key))
|
28
|
+
res[:exceptions].map! { |item| Object.const_get(item) if item.instance_of?(String) }
|
29
|
+
res
|
30
|
+
end
|
31
|
+
|
32
|
+
# defined and store value for specified key
|
33
|
+
# @param key [Symbol] :key the name of the record
|
34
|
+
# @param value [Symbol] :value the content value of the record
|
35
|
+
# @return [String] content value of record
|
36
|
+
def put(key:, value:)
|
37
|
+
data = value.dup
|
38
|
+
data[:exceptions].map! { |item| item.name.to_s if item.instance_of?(Class) }
|
39
|
+
@be.set key, data.to_yaml
|
40
|
+
end
|
41
|
+
|
42
|
+
# delete a specific record
|
43
|
+
# @param key [Symbol] the name of the record
|
44
|
+
# @return [Boolean] status of the operation
|
45
|
+
def del(key:)
|
46
|
+
@be.del key
|
47
|
+
end
|
48
|
+
|
49
|
+
# flush all records in backend
|
50
|
+
# @return [Boolean] status of the operation
|
51
|
+
def flush
|
52
|
+
@be.flushdb
|
53
|
+
end
|
5
54
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
@config = config.slice(:host, :port, :db)
|
12
|
-
@be = ::Redis.new @config
|
13
|
-
@be.auth(@auth) if @auth
|
14
|
-
end
|
15
|
-
|
16
|
-
# return the list of find records in backend for a specific pattern
|
17
|
-
# @return [Array] list of record (for all hostname if hostname is specified)
|
18
|
-
def list
|
19
|
-
return @be.keys('*').map(&:to_sym)
|
20
|
-
end
|
21
|
-
|
22
|
-
|
23
|
-
# return value of queried record
|
24
|
-
# @param key [Symbol] the name of the record
|
25
|
-
# @return [String] content value of record
|
26
|
-
def get(key:)
|
27
|
-
res = YAML.load(@be.get(key))
|
28
|
-
res[:exceptions].map! {|item| item = Object.const_get(item) if item.class == String }
|
29
|
-
return res
|
30
|
-
end
|
31
|
-
|
32
|
-
# defined and store value for specified key
|
33
|
-
# @param key [Symbol] :key the name of the record
|
34
|
-
# @param value [Symbol] :value the content value of the record
|
35
|
-
# @return [String] content value of record
|
36
|
-
def put(key: ,value:)
|
37
|
-
data = value.dup
|
38
|
-
data[:exceptions].map! {|item| item = item.name.to_s if item.class == Class }
|
39
|
-
@be.set key, data.to_yaml
|
40
|
-
end
|
41
|
-
|
42
|
-
# delete a specific record
|
43
|
-
# @param key [Symbol] the name of the record
|
44
|
-
# @return [Boolean] status of the operation
|
45
|
-
def del(key: )
|
46
|
-
@be.del key
|
47
|
-
end
|
48
|
-
|
49
|
-
# flush all records in backend
|
50
|
-
# @return [Boolean] status of the operation
|
51
|
-
def flush
|
52
|
-
@be.flushdb
|
53
|
-
end
|
54
|
-
|
55
|
-
# verifiy a specific record existence
|
56
|
-
# @param key [Symbol] the name of the record
|
57
|
-
# @return [Boolean] presence of the record
|
58
|
-
def exist?(key: )
|
59
|
-
return ( not @be.get(key).nil?)
|
60
|
-
end
|
61
|
-
|
62
|
-
|
55
|
+
# verifiy a specific record existence
|
56
|
+
# @param key [Symbol] the name of the record
|
57
|
+
# @return [Boolean] presence of the record
|
58
|
+
def exist?(key:)
|
59
|
+
!@be.get(key).nil?
|
63
60
|
end
|
64
|
-
|
65
61
|
end
|
66
|
-
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/sc4ry/circuits.rb
CHANGED
@@ -1,84 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Sc4ry Module
|
2
4
|
# @note namespace
|
3
5
|
module Sc4ry
|
4
|
-
|
5
6
|
# Circuits and default configuration management class
|
6
7
|
class Circuits
|
7
|
-
|
8
8
|
include Sc4ry::Constants
|
9
9
|
include Sc4ry::Exceptions
|
10
10
|
|
11
|
-
@@circuits_store = Sc4ry::Store.instance
|
11
|
+
@@circuits_store = Sc4ry::Store.instance
|
12
12
|
@@circuits_notifiers = Sc4ry::Notifiers
|
13
13
|
@@circuits_loggers = Sc4ry::Loggers
|
14
14
|
@@config = DEFAULT_CONFIG
|
15
15
|
|
16
|
-
# @!group forwarders
|
16
|
+
# @!group forwarders
|
17
17
|
|
18
18
|
# Class method how forward the Notifiers class factory/manager
|
19
19
|
# @return [Sc4ry::Notifiers]
|
20
|
-
def
|
21
|
-
|
20
|
+
def self.notifiers
|
21
|
+
@@circuits_notifiers
|
22
22
|
end
|
23
23
|
|
24
24
|
# Class method how forward a Store manager class singleton
|
25
25
|
# @return [Sc4ry::Store]
|
26
|
-
def
|
27
|
-
|
26
|
+
def self.store
|
27
|
+
@@circuits_store
|
28
28
|
end
|
29
29
|
|
30
30
|
# Class method how forward the Logger manager class factory/manager
|
31
31
|
# @return [Sc4ry::Store]
|
32
|
-
def
|
33
|
-
|
32
|
+
def self.loggers
|
33
|
+
@@circuits_loggers
|
34
34
|
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
36
|
# @!endgroup
|
39
37
|
|
40
|
-
|
41
38
|
# @!group Default Sc4ry configuration management
|
42
39
|
|
43
40
|
# Class method how return de default Sc4ry config
|
44
|
-
# @return [Hash]
|
45
|
-
def
|
46
|
-
|
41
|
+
# @return [Hash]
|
42
|
+
def self.default_config
|
43
|
+
@@config
|
47
44
|
end
|
48
45
|
|
49
46
|
# class method how merge a differential hash to default config
|
50
47
|
# @param [Hash] diff the differential hash config
|
51
48
|
# @example usage
|
52
49
|
# include Sc4ry
|
53
|
-
# Circuits.merge_default_config diff: {max_time: 20, notifiers: [:mattermost]}
|
54
|
-
def
|
55
|
-
validator = Sc4ry::Config::Validator
|
50
|
+
# Circuits.merge_default_config diff: {max_time: 20, notifiers: [:mattermost]}
|
51
|
+
def self.merge_default_config(diff:)
|
52
|
+
validator = Sc4ry::Config::Validator.new(definition: diff, from: @@config)
|
56
53
|
validator.validate!
|
57
|
-
@@config = validator.result
|
58
|
-
|
54
|
+
@@config = validator.result
|
59
55
|
end
|
60
56
|
|
61
|
-
# class method for specifiying config by block
|
57
|
+
# class method for specifiying config by block
|
62
58
|
# @yield [Sc4ry::Config::ConfigMapper]
|
63
59
|
# @example usage
|
64
60
|
# include Sc4ry
|
65
61
|
# Circuits.configure do |spec|
|
66
|
-
# spec.max_failure_count = 3
|
62
|
+
# spec.max_failure_count = 3
|
67
63
|
# end
|
68
|
-
def
|
69
|
-
mapper = Sc4ry::Config::ConfigMapper
|
64
|
+
def self.configure
|
65
|
+
mapper = Sc4ry::Config::ConfigMapper.new(definition: @@config.dup)
|
70
66
|
yield(mapper)
|
71
|
-
validator = Sc4ry::Config::Validator
|
67
|
+
validator = Sc4ry::Config::Validator.new(definition: mapper.config, from: @@config)
|
72
68
|
validator.validate!
|
73
|
-
@@config = validator.result
|
69
|
+
@@config = validator.result
|
74
70
|
end
|
75
71
|
|
76
|
-
|
77
|
-
# old default config setter
|
72
|
+
# old default config setter
|
78
73
|
# @deprecated use {.merge_default_config} instead
|
79
74
|
# @param [Hash] config
|
80
|
-
def
|
81
|
-
|
75
|
+
def self.default_config=(config)
|
76
|
+
warning_mess = 'DEPRECATED: Circuits.default_config= use Circuits.merge_default_config add: {<config_hash>}'
|
77
|
+
Sc4ry::Helpers.log level: :warn,
|
78
|
+
message: warning_mess
|
82
79
|
Circuits.merge_default_config(diff: config)
|
83
80
|
end
|
84
81
|
|
@@ -91,77 +88,77 @@ module Sc4ry
|
|
91
88
|
# @param [Symbol] circuit a circuit name
|
92
89
|
# @param [Hash] config a config override on default config for the circuit
|
93
90
|
# @example usage
|
94
|
-
# include Sc4ry
|
91
|
+
# include Sc4ry
|
95
92
|
# Circuits.register circuit: :mycircuit, config: {raise_on_opening: true, timeout: true}
|
96
93
|
# # or
|
97
94
|
# Circuits.register circuit: :mycircuit do |spec|
|
98
95
|
# spec.raise_on_opening = true
|
99
96
|
# spec.timeout = true
|
100
97
|
# end
|
101
|
-
# @return [Hash] the full config of the circuit after merge on default
|
98
|
+
# @return [Hash] the full config of the circuit after merge on default
|
102
99
|
# @raise [Sc4ryGenericError] if use config keyword with a block
|
103
100
|
# @raise [Sc4ryGenericError] if circuit already exist in current store.
|
104
|
-
def
|
105
|
-
if config.
|
106
|
-
raise Sc4ryGenericError,
|
101
|
+
def self.register(circuit:, config: {})
|
102
|
+
if !config.empty? && block_given?
|
103
|
+
raise Sc4ryGenericError,
|
104
|
+
'config: keyword must not be defined when block is given'
|
107
105
|
end
|
108
|
-
|
109
|
-
|
106
|
+
|
107
|
+
if block_given?
|
108
|
+
mapper = Sc4ry::Config::ConfigMapper.new(definition: @@config.dup)
|
110
109
|
yield(mapper)
|
111
|
-
validator = Sc4ry::Config::Validator
|
112
|
-
else
|
113
|
-
validator = Sc4ry::Config::Validator
|
110
|
+
validator = Sc4ry::Config::Validator.new(definition: mapper.config, from: @@config.dup)
|
111
|
+
else
|
112
|
+
validator = Sc4ry::Config::Validator.new(definition: config, from: @@config.dup)
|
114
113
|
end
|
115
114
|
validator.validate!
|
116
115
|
Sc4ry::Helpers.log level: :debug, message: "Circuit #{circuit} : registered"
|
117
|
-
raise Sc4ryGenericError, "Circuit: #{circuit} already exist in store" if @@circuits_store.exist? key: circuit
|
118
|
-
|
119
|
-
|
116
|
+
raise Sc4ryGenericError, "Circuit: #{circuit} already exist in store" if @@circuits_store.exist? key: circuit
|
117
|
+
|
118
|
+
@@circuits_store.put key: circuit, value: validator.result
|
119
|
+
validator.result
|
120
120
|
end
|
121
121
|
|
122
122
|
# class method how list all circuits in current store
|
123
123
|
# @example usage
|
124
|
-
# include Sc4ry
|
124
|
+
# include Sc4ry
|
125
125
|
# circuits = Circuits.list
|
126
126
|
# @return [Array] the list of [Symbol] circuits name
|
127
|
-
def
|
128
|
-
|
127
|
+
def self.list
|
128
|
+
@@circuits_store.list
|
129
129
|
end
|
130
130
|
|
131
131
|
# class method how flush all circuits in current store
|
132
132
|
# @example usage
|
133
|
-
# include Sc4ry
|
133
|
+
# include Sc4ry
|
134
134
|
# Circuits.flush
|
135
|
-
# @return [true,false]
|
136
|
-
def
|
137
|
-
|
135
|
+
# @return [true,false]
|
136
|
+
def self.flush
|
137
|
+
@@circuits_store.flush
|
138
138
|
end
|
139
139
|
|
140
140
|
# class method for unregistering a circuit
|
141
141
|
# @param [Symbol] circuit a circuit name
|
142
142
|
# @example usage
|
143
|
-
# include Sc4ry
|
143
|
+
# include Sc4ry
|
144
144
|
# Circuits.unregister circuit: :mycircuit
|
145
145
|
# @raise [Sc4ryGenericError] if circuit not found in current store.
|
146
146
|
# @return [true,false]
|
147
|
-
def
|
148
|
-
|
149
|
-
@@circuits_store.del key: circuit
|
150
|
-
return true
|
151
|
-
else
|
152
|
-
raise Sc4ryGenericError, "Circuit #{circuit} not found"
|
153
|
-
return false
|
154
|
-
end
|
155
|
-
end
|
147
|
+
def self.unregister(circuit:)
|
148
|
+
raise Sc4ryGenericError, "Circuit #{circuit} not found" unless Circuits.list.include? circuit
|
156
149
|
|
150
|
+
@@circuits_store.del key: circuit
|
151
|
+
Sc4ry::Helpers.log level: :debug, message: "Circuit #{circuit} : unregistered"
|
152
|
+
true
|
153
|
+
end
|
157
154
|
|
158
155
|
# class method for get a specific circuit by circuit name
|
159
156
|
# @param [Symbol] circuit a circuit name
|
160
157
|
# @example usage
|
161
|
-
# include Sc4ry
|
158
|
+
# include Sc4ry
|
162
159
|
# Circuits.get circuit: :mycircuit
|
163
160
|
# @return [Hash] the circuit record in current store included values and status if the circuit have already run.
|
164
|
-
def
|
161
|
+
def self.get(circuit:)
|
165
162
|
@@circuits_store.get key: circuit
|
166
163
|
end
|
167
164
|
|
@@ -169,91 +166,93 @@ module Sc4ry
|
|
169
166
|
# @param [Symbol] circuit a circuit name
|
170
167
|
# @param [Hash] config a config hash to merge on current config
|
171
168
|
# @example usage
|
172
|
-
# include Sc4ry
|
169
|
+
# include Sc4ry
|
173
170
|
# Circuits.update_config circuit: :mycircuit, config: {}
|
174
|
-
# @note : <b>important</b> updating config will reset status and values !
|
171
|
+
# @note : <b>important</b> updating config will reset status and values !
|
175
172
|
# @return [Hash] new config for this circuit
|
176
|
-
def
|
173
|
+
def self.update_config(circuit:, config: { forward_unknown_exceptions: false })
|
177
174
|
raise Sc4ryGenericError, "Circuit #{circuit} not found" unless Circuits.list.include? circuit
|
175
|
+
|
178
176
|
save = @@circuits_store.get key: circuit
|
179
|
-
save.delete_if {|key,
|
177
|
+
save.delete_if { |key, _val| %i[status values].include? key }
|
180
178
|
Circuits.unregister(circuit: circuit)
|
181
179
|
save.merge! config
|
182
|
-
|
180
|
+
Circuits.register circuit: circuit, config: save
|
183
181
|
end
|
184
182
|
|
185
183
|
# class method for get the status of a specific circuit by circuit name
|
186
184
|
# @param [Symbol] circuit a circuit name
|
187
185
|
# @example usage
|
188
|
-
# include Sc4ry
|
186
|
+
# include Sc4ry
|
189
187
|
# Circuits.status circuit: :mycircuit
|
190
|
-
# @return [Symbol] status must in [:open,:half_open,:closed,:never_run]
|
191
|
-
def
|
188
|
+
# @return [Symbol] status must in [:open,:half_open,:closed,:never_run]
|
189
|
+
def self.status(circuit:)
|
192
190
|
data = @@circuits_store.get key: circuit
|
193
|
-
|
191
|
+
data.include?(:status) ? data[:status][:general] : :never_run
|
194
192
|
end
|
195
193
|
|
196
|
-
|
197
194
|
# class method for running circuit, need a block
|
198
195
|
# @yield [Proc]
|
199
196
|
# @param [Symbol] circuit a circuit name
|
200
197
|
# @example usage
|
201
|
-
# include Sc4ry
|
202
|
-
# Circuits.run circuit: :mycircuit do
|
198
|
+
# include Sc4ry
|
199
|
+
# Circuits.run circuit: :mycircuit do
|
203
200
|
# # [...] your code like a Restclient.get("URL")
|
204
201
|
# end
|
205
202
|
# # or
|
206
|
-
# Circuits.run do
|
203
|
+
# Circuits.run do
|
207
204
|
# # [...] your code like a Restclient.get("URL")
|
208
205
|
# # running with the first define circuit (use only on a one circuit usage)
|
209
206
|
# end
|
210
207
|
# @return [Hash] a result like ":general=>:open, :failure_count=>X, :overtime_count=>X, :timeout_count=>X"
|
211
|
-
# @raise [Sc4ryGenericError] if circuit already not exit, block is missing or store empty
|
212
|
-
def
|
208
|
+
# @raise [Sc4ryGenericError] if circuit already not exit, block is missing or store empty
|
209
|
+
def self.run(circuit: nil, &block)
|
213
210
|
circuits_list = Circuits.list
|
214
|
-
raise Sc4ryGenericError,
|
215
|
-
raise Sc4ryGenericError,
|
216
|
-
|
211
|
+
raise Sc4ryGenericError, 'No circuit block given' unless block_given?
|
212
|
+
raise Sc4ryGenericError, 'No circuits defined' if circuits_list.empty?
|
213
|
+
|
214
|
+
circuit_name = circuit || circuits_list.first
|
217
215
|
raise Sc4ryGenericError, "Circuit #{circuit_name} not found" unless circuits_list.include? circuit_name
|
216
|
+
|
218
217
|
circuit_to_run = Circuits.get circuit: circuit_name
|
219
218
|
skip = false
|
220
|
-
if circuit_to_run.include? :status
|
221
|
-
|
222
|
-
|
223
|
-
skip = true if ((@now - circuit_to_run[:values].last[:end_time]) < circuit_to_run[:check_delay])
|
224
|
-
end
|
219
|
+
if circuit_to_run.include?(:status) && (circuit_to_run[:status][:general] == :open)
|
220
|
+
@now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
221
|
+
skip = true if (@now - circuit_to_run[:values].last[:end_time]) < circuit_to_run[:check_delay]
|
225
222
|
end
|
226
|
-
unless skip
|
223
|
+
unless skip
|
227
224
|
controller = Sc4ry::RunController.new(circuit_to_run)
|
228
225
|
Circuits.control circuit: circuit_name, values: controller.run(block: block)
|
229
226
|
end
|
230
227
|
result = @@circuits_store.get key: circuit_name
|
231
228
|
Sc4ry::Helpers.log level: :debug, message: "Circuit #{circuit_name} : status #{result[:status]}"
|
232
|
-
|
229
|
+
result
|
233
230
|
end
|
234
231
|
|
235
232
|
# @!endgroup
|
236
233
|
|
237
|
-
private
|
238
234
|
# the private class method to control circuits running status
|
239
235
|
# @param [Symbol] circuit the name the circuit to control
|
240
|
-
# @param [Hash] values the resut value of a run
|
241
|
-
# @return [Boolean]
|
242
|
-
def
|
236
|
+
# @param [Hash] values the resut value of a run
|
237
|
+
# @return [Boolean]
|
238
|
+
def self.control(circuit:, values:)
|
243
239
|
data = @@circuits_store.get key: circuit
|
244
|
-
|
245
|
-
|
240
|
+
unless data.include? :status
|
241
|
+
data[:status] =
|
242
|
+
{ general: :closed, failure_count: 0, overtime_count: 0, timeout_count: 0 }
|
243
|
+
end
|
244
|
+
data[:values] = [] unless data.include? :values
|
246
245
|
level = [data[:max_failure_count].to_i, data[:max_timeout_count].to_i, data[:max_overtime_count].to_i].max
|
247
246
|
data[:values].shift if data[:values].size > level
|
248
247
|
data[:values].push values
|
249
248
|
worst_status = []
|
250
|
-
[
|
251
|
-
if values[control.to_sym] == true
|
249
|
+
%w[failure overtime timeout].each do |control|
|
250
|
+
if values[control.to_sym] == true
|
252
251
|
data[:status]["#{control}_count".to_sym] += 1
|
253
252
|
else
|
254
253
|
data[:status]["#{control}_count".to_sym] = 0
|
255
254
|
end
|
256
|
-
|
255
|
+
|
257
256
|
case data[:status]["#{control}_count".to_sym]
|
258
257
|
when 0
|
259
258
|
worst_status.push :closed
|
@@ -264,16 +263,23 @@ module Sc4ry
|
|
264
263
|
end
|
265
264
|
end
|
266
265
|
save = data[:status][:general]
|
267
|
-
[
|
266
|
+
%i[closed half_open open].each do |status|
|
268
267
|
data[:status][:general] = status if worst_status.include? status
|
269
268
|
end
|
270
|
-
if save != data[:status][:general]
|
271
|
-
raise CircuitBreaked if data[:status][:general] == :open
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
269
|
+
if save != data[:status][:general]
|
270
|
+
raise CircuitBreaked if data[:status][:general] == :open && data[:raise_on_opening]
|
271
|
+
|
272
|
+
if data[:status][:general] == :open
|
273
|
+
Sc4ry::Helpers.log level: :error,
|
274
|
+
message: "Circuit #{circuit} : breacking ! "
|
275
|
+
end
|
276
|
+
if data[:status][:general] == :closed
|
277
|
+
Sc4ry::Helpers.log level: :info,
|
278
|
+
message: "Circuit #{circuit} : is now closed"
|
279
|
+
end
|
280
|
+
Sc4ry::Helpers.notify circuit: circuit, config: data
|
281
|
+
end
|
276
282
|
@@circuits_store.put key: circuit, value: data
|
277
283
|
end
|
278
284
|
end
|
279
|
-
end
|
285
|
+
end
|