sc4ry 0.1.6 → 0.2.0
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/.github/workflows/main.yml +27 -0
- data/.gitignore +1 -1
- data/Gemfile +4 -1
- data/README.md +69 -24
- data/Rakefile +31 -0
- data/VERSION +1 -0
- data/assets/images/sc4ry_workflow.png +0 -0
- data/lib/sc4ry/backends/memory.rb +35 -8
- data/lib/sc4ry/backends/redis.rb +21 -20
- data/lib/sc4ry/circuits.rb +217 -40
- data/lib/sc4ry/config.rb +91 -0
- data/lib/sc4ry/constants.rb +51 -0
- data/lib/sc4ry/dependencies.rb +12 -3
- data/lib/sc4ry/exceptions.rb +39 -0
- data/lib/sc4ry/helpers.rb +20 -6
- data/lib/sc4ry/logger.rb +45 -9
- data/lib/sc4ry/notifiers/init.rb +41 -14
- data/lib/sc4ry/notifiers/mattermost.rb +26 -18
- data/lib/sc4ry/notifiers/prometheus.rb +7 -1
- data/lib/sc4ry/run_controller.rb +22 -6
- data/lib/sc4ry/store.rb +74 -11
- data/lib/sc4ry/version.rb +7 -1
- data/sc4ry.gemspec +7 -3
- data/ultragreen_roodi_coding_convention.yml +25 -0
- metadata +96 -7
- data/assets/logo_sc4ry.png +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f4cbfc8c2a7a821c3374916cdd69650a91f1eca5faa4dbbd93ac94e29dae5f89
|
4
|
+
data.tar.gz: dfa68d210342122e96e6f9fcd234fa73f6fefee667addac8371424b39c1b63d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82590002c1ac457715776b0be304d77fa2903885cc4dc21ee45cea87ee070648661b48520453ab011cd287da49997990b4e607940a54954f5f82b5c884089715
|
7
|
+
data.tar.gz: 8b63d6b39cee270a1e1ab38ffcde491b746011126615bc4a5908b9f8790017f0c30c8899453ca1848ee4022f8528a0edd61587b583d58a8404e4eef139ecbb84
|
@@ -0,0 +1,27 @@
|
|
1
|
+
name: Ruby
|
2
|
+
|
3
|
+
on: [push,pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
container-job:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
container: ruby:latest
|
9
|
+
services:
|
10
|
+
redis:
|
11
|
+
image: redis
|
12
|
+
pushgateway:
|
13
|
+
image: prom/pushgateway
|
14
|
+
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v2
|
17
|
+
- name: Run the default task
|
18
|
+
run: |
|
19
|
+
gem install bundler -v 2.2.3
|
20
|
+
bundle install
|
21
|
+
bundle exec rake
|
22
|
+
env:
|
23
|
+
# The hostname used to communicate with the Redis service container
|
24
|
+
REDIS_HOST: redis
|
25
|
+
REDIS_PORT: 6379
|
26
|
+
PROM_PG_PORT: 9091
|
27
|
+
PROM_PG_HOST: pushgateway
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,25 @@
|
|
2
2
|
|
3
3
|
Sc4ry provide the Circuit Breaker Design Pattern for your applications
|
4
4
|
|
5
|
-
](https://github.com/Ultragreen/sc4ry/actions?query=workflow%3ARuby+branch%3Amaster)
|
6
|
+

|
7
|
+
|
8
|
+
[](https://rubydoc.info/gems/sc4ry)
|
9
|
+

|
10
|
+

|
11
|
+

|
12
|
+

|
13
|
+
|
14
|
+

|
15
|
+
[](https://badge.fury.io/rb/sc4ry)
|
16
|
+

|
17
|
+

|
18
|
+

|
19
|
+
|
20
|
+
<noscript><a href="https://liberapay.com/ruydiaz/donate"><img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg"></a></noscript>
|
21
|
+
|
22
|
+

|
23
|
+
_Simple CircuitBreacker 4 RubY_
|
6
24
|
|
7
25
|
## Installation
|
8
26
|
|
@@ -22,6 +40,9 @@ Or install it yourself as:
|
|
22
40
|
|
23
41
|
## Usage
|
24
42
|
|
43
|
+
### Circuits States Worflow
|
44
|
+
|
45
|
+

|
25
46
|
### sample with Restclient
|
26
47
|
|
27
48
|
```ruby
|
@@ -30,39 +51,64 @@ require 'rubygems'
|
|
30
51
|
require 'sc4ry'
|
31
52
|
|
32
53
|
|
54
|
+
puts 'Initial default config'
|
55
|
+
pp Sc4ry::Circuits.default_config
|
56
|
+
|
57
|
+
|
58
|
+
Sc4ry::Circuits.merge_default_config diff: {timeout: true }
|
59
|
+
# or with a block
|
60
|
+
Sc4ry::Circuits.configure do |spec|
|
61
|
+
spec.max_time = 12
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
# display default config
|
66
|
+
puts 'Default config'
|
67
|
+
pp Sc4ry::Circuits.default_config
|
68
|
+
|
69
|
+
|
33
70
|
# defining a circuit, config must be empty or override from default
|
34
|
-
Sc4ry::Circuits.register
|
71
|
+
Sc4ry::Circuits.register circuit: :test, config: {:notifiers => [:prometheus,:mattermost], :exceptions => [Errno::ECONNREFUSED, URI::InvalidURIError] }
|
72
|
+
# or with a block
|
73
|
+
Sc4ry::Circuits.register circuit: :test2 do |spec|
|
74
|
+
spec.exceptions = [Errno::ECONNREFUSED]
|
75
|
+
end
|
76
|
+
# or
|
77
|
+
Sc4ry::Circuits.register circuit: :test3
|
35
78
|
|
36
|
-
# display the list of known circuit
|
37
|
-
pp Sc4ry::Circuits.list
|
38
79
|
|
39
|
-
# display default config, must be override with a nested hash by calling default_config= method
|
40
|
-
pp Sc4ry::Circuits.default_config
|
41
80
|
|
81
|
+
puts "Circuits list"
|
82
|
+
pp Sc4ry::Circuits::list
|
42
83
|
|
43
|
-
# Config an alternate logger
|
84
|
+
# Config an alternate logger
|
44
85
|
Sc4ry::Logger.register name: :perso, instance: ::Logger.new('/tmp/logfile.log')
|
45
|
-
Sc4ry::Logger::current = :
|
86
|
+
Sc4ry::Logger::current = :stdout
|
46
87
|
|
47
88
|
|
48
89
|
# default values, circuit is half open before one of the max count is reached
|
49
90
|
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
91
|
+
# DEFAULT_CONFIG = {
|
92
|
+
# :max_failure_count => 5,
|
93
|
+
# :timeout_value => 20,
|
94
|
+
# :timeout => false,
|
95
|
+
# :max_timeout_count => 5,
|
96
|
+
# :max_time => 10,
|
97
|
+
# :max_overtime_count => 3,
|
98
|
+
# :check_delay => 30,
|
99
|
+
# :notifiers => [],
|
100
|
+
# :forward_unknown_exceptions => true,
|
101
|
+
# :raise_on_opening => false,
|
102
|
+
# :exceptions => [StandardError, RuntimeError]
|
103
|
+
# }
|
61
104
|
|
62
105
|
# display configuration for a specific circuit
|
63
|
-
|
106
|
+
Sc4ry::Circuits::list.each do |circuit|
|
107
|
+
puts "Config #{circuit} :"
|
108
|
+
pp Sc4ry::Circuits.get circuit: circuit
|
109
|
+
end
|
64
110
|
|
65
|
-
# sample Mattermost notification
|
111
|
+
# sample Mattermost notification
|
66
112
|
#Sc4ry::Notifiers::config({:name => :mattermost, :config => {:url => 'https://mattermost.mycorp.com', :token => "<TOKEN>"}})
|
67
113
|
|
68
114
|
# sample loop
|
@@ -70,7 +116,7 @@ pp Sc4ry::Circuits.get circuit: :test
|
|
70
116
|
sleep 1
|
71
117
|
Sc4ry::Circuits.run circuit: :test do
|
72
118
|
# for the test choose or build an endpoint you must shutdown
|
73
|
-
puts RestClient.get('http://<
|
119
|
+
puts RestClient.get('http://<URL_OF_AN_ENDPOINT>')
|
74
120
|
end
|
75
121
|
end
|
76
122
|
|
@@ -84,8 +130,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
84
130
|
|
85
131
|
## Contributing
|
86
132
|
|
87
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
88
|
-
|
133
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/Ultragreen/sc4ry.
|
89
134
|
|
90
135
|
## License
|
91
136
|
|
data/Rakefile
CHANGED
@@ -1,6 +1,37 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rspec/core/rake_task"
|
3
|
+
require 'yard'
|
4
|
+
require 'yard/rake/yardoc_task.rb'
|
5
|
+
require 'code_statistics'
|
6
|
+
require "roodi"
|
7
|
+
require "roodi_task"
|
8
|
+
require "version"
|
9
|
+
require 'rake/version_task'
|
10
|
+
Rake::VersionTask.new
|
11
|
+
|
12
|
+
|
13
|
+
RoodiTask.new() do | t |
|
14
|
+
t.patterns = %w(lib/**/*.rb)
|
15
|
+
t.config = "ultragreen_roodi_coding_convention.yml"
|
16
|
+
end
|
17
|
+
|
3
18
|
|
4
19
|
RSpec::Core::RakeTask.new(:spec)
|
5
20
|
|
6
21
|
task :default => :spec
|
22
|
+
|
23
|
+
|
24
|
+
YARD::Rake::YardocTask.new do |t|
|
25
|
+
t.files = [ 'lib/**/*.rb', '-', 'doc/**/*','spec/**/*_spec.rb']
|
26
|
+
t.options += ['-o', "yardoc"]
|
27
|
+
end
|
28
|
+
YARD::Config.load_plugin('yard-rspec')
|
29
|
+
|
30
|
+
namespace :yardoc do
|
31
|
+
task :clobber do
|
32
|
+
rm_r "yardoc" rescue nil
|
33
|
+
rm_r ".yardoc" rescue nil
|
34
|
+
rm_r "pkg" rescue nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
task :clobber => "yardoc:clobber"
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.2.0
|
Binary file
|
@@ -1,33 +1,60 @@
|
|
1
|
+
# Sc4ry module
|
2
|
+
# @note namespace
|
1
3
|
module Sc4ry
|
4
|
+
|
5
|
+
# Sc4ry:Backends module
|
6
|
+
# @note namespace
|
2
7
|
module Backends
|
3
8
|
|
9
|
+
# class of the memory backend
|
4
10
|
class Memory
|
11
|
+
|
12
|
+
# Constructor
|
13
|
+
# @param [Hash] config Config map
|
14
|
+
# @return [Sc4ry::Backends::Memory] a in Memory backend
|
5
15
|
def initialize(config=nil?)
|
6
16
|
@data = Hash::new
|
7
17
|
end
|
8
18
|
|
19
|
+
# return the list of find records in backend for a specific pattern
|
20
|
+
# @return [Array] list of record (for all hostname if hostname is specified)
|
9
21
|
def list
|
10
22
|
return @data.keys
|
11
23
|
end
|
12
24
|
|
13
|
-
|
14
|
-
|
25
|
+
# return value of queried record
|
26
|
+
# @param key [Symbol] the name of the record
|
27
|
+
# @return [String] content value of record
|
28
|
+
def get(key: )
|
29
|
+
return @data[key]
|
15
30
|
end
|
16
31
|
|
17
|
-
|
18
|
-
|
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[key] = value
|
19
38
|
end
|
20
39
|
|
21
|
-
|
22
|
-
|
40
|
+
# delete a specific record
|
41
|
+
# @param params [Symbol] the name of the record
|
42
|
+
# @return [Boolean] status of the operation
|
43
|
+
def del(key: )
|
44
|
+
@data.delete key
|
23
45
|
end
|
24
46
|
|
47
|
+
# flush all records in backend
|
48
|
+
# @return [Boolean] status of the operation
|
25
49
|
def flush
|
26
50
|
@data.clear
|
27
51
|
end
|
28
52
|
|
29
|
-
|
30
|
-
|
53
|
+
# verifiy a specific record existence
|
54
|
+
# @param key [Symbol] the name of the record
|
55
|
+
# @return [Boolean] presence of the record
|
56
|
+
def exist?(key: )
|
57
|
+
return @data.include? key
|
31
58
|
end
|
32
59
|
|
33
60
|
end
|
data/lib/sc4ry/backends/redis.rb
CHANGED
@@ -16,46 +16,47 @@ module Sc4ry
|
|
16
16
|
# return the list of find records in backend for a specific pattern
|
17
17
|
# @return [Array] list of record (for all hostname if hostname is specified)
|
18
18
|
def list
|
19
|
-
return @
|
19
|
+
return @be.keys('*').map(&:to_sym)
|
20
20
|
end
|
21
21
|
|
22
22
|
|
23
23
|
# return value of queried record
|
24
|
-
# @param [
|
25
|
-
# @option options [Symbol] :key the name of the record
|
24
|
+
# @param key [Symbol] the name of the record
|
26
25
|
# @return [String] content value of record
|
27
|
-
def get(
|
28
|
-
|
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
|
29
30
|
end
|
30
31
|
|
31
32
|
# defined and store value for specified key
|
32
|
-
# @param [
|
33
|
-
# @
|
34
|
-
# @option options [Symbol] :value the content value of the record
|
33
|
+
# @param key [Symbol] :key the name of the record
|
34
|
+
# @param value [Symbol] :value the content value of the record
|
35
35
|
# @return [String] content value of record
|
36
|
-
def put(
|
37
|
-
|
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
|
38
40
|
end
|
39
41
|
|
40
42
|
# delete a specific record
|
41
|
-
# @param [
|
42
|
-
# @option options [Symbol] :key the name of the record
|
43
|
+
# @param key [Symbol] the name of the record
|
43
44
|
# @return [Boolean] status of the operation
|
44
|
-
def del(
|
45
|
-
@
|
45
|
+
def del(key: )
|
46
|
+
@be.del key
|
46
47
|
end
|
47
48
|
|
48
49
|
# flush all records in backend
|
50
|
+
# @return [Boolean] status of the operation
|
49
51
|
def flush
|
50
|
-
@
|
52
|
+
@be.flushdb
|
51
53
|
end
|
52
54
|
|
53
|
-
# verifiy a specific record
|
54
|
-
# @param [
|
55
|
-
# @option options [Symbol] :key the name of the record
|
55
|
+
# verifiy a specific record existence
|
56
|
+
# @param key [Symbol] the name of the record
|
56
57
|
# @return [Boolean] presence of the record
|
57
|
-
def exist?(
|
58
|
-
return ( not @
|
58
|
+
def exist?(key: )
|
59
|
+
return ( not @be.get(key).nil?)
|
59
60
|
end
|
60
61
|
|
61
62
|
|