faulty 0.1.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +49 -0
- data/.rubocop.yml +9 -0
- data/CHANGELOG.md +50 -2
- data/Gemfile +22 -0
- data/README.md +836 -220
- data/bin/check-version +5 -1
- data/bin/console +1 -1
- data/faulty.gemspec +4 -11
- data/lib/faulty.rb +157 -43
- data/lib/faulty/cache.rb +3 -1
- data/lib/faulty/cache/auto_wire.rb +58 -0
- data/lib/faulty/cache/circuit_proxy.rb +61 -0
- data/lib/faulty/cache/default.rb +10 -21
- data/lib/faulty/cache/fault_tolerant_proxy.rb +15 -4
- data/lib/faulty/cache/interface.rb +1 -1
- data/lib/faulty/cache/mock.rb +1 -1
- data/lib/faulty/cache/null.rb +1 -1
- data/lib/faulty/cache/rails.rb +9 -10
- data/lib/faulty/circuit.rb +10 -5
- data/lib/faulty/error.rb +18 -4
- data/lib/faulty/events.rb +3 -2
- data/lib/faulty/events/callback_listener.rb +1 -1
- data/lib/faulty/events/honeybadger_listener.rb +53 -0
- data/lib/faulty/events/listener_interface.rb +1 -1
- data/lib/faulty/events/log_listener.rb +5 -6
- data/lib/faulty/events/notifier.rb +11 -2
- data/lib/faulty/immutable_options.rb +1 -1
- data/lib/faulty/result.rb +2 -2
- data/lib/faulty/status.rb +3 -2
- data/lib/faulty/storage.rb +4 -1
- data/lib/faulty/storage/auto_wire.rb +107 -0
- data/lib/faulty/storage/circuit_proxy.rb +64 -0
- data/lib/faulty/storage/fallback_chain.rb +207 -0
- data/lib/faulty/storage/fault_tolerant_proxy.rb +51 -56
- data/lib/faulty/storage/interface.rb +1 -1
- data/lib/faulty/storage/memory.rb +8 -4
- data/lib/faulty/storage/redis.rb +75 -13
- data/lib/faulty/version.rb +2 -2
- metadata +18 -122
- data/.travis.yml +0 -44
- data/lib/faulty/scope.rb +0 -117
data/.travis.yml
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
---
|
2
|
-
language: ruby
|
3
|
-
rvm:
|
4
|
-
- 2.3
|
5
|
-
- 2.4
|
6
|
-
- 2.5
|
7
|
-
- 2.6
|
8
|
-
- 2.7
|
9
|
-
|
10
|
-
env:
|
11
|
-
global:
|
12
|
-
- COVERAGE=1
|
13
|
-
# Encrypted code climate CC_TEST_REPORTER_ID=
|
14
|
-
- secure: 'a/qmESTnDq37KvBY4u1VcBEjd7Y3b16L28AiV0y3d7SbrGeuWPmTR7WMvD8b0CV1Ou5wpic9HAxC9u2ZYhy0/BN9I4AOnkyj4IXF9K+ETbTq2XOAix38hNF4a/Hl89mgKD3IPtjxVrQ83h7pxbqtQ2jPnLyiR7mTj0rfOmzTSaItcn/auONuvanHuitGjYTw3xUA1okbhMy8cVh3nbozP0m3eujSbSOpLD3N9+s+A8lE+6VbNvoygqoqdcQqlYH4q5x+SGaD7L1illIywxVWpExygB9jIum3mhaXe7ThJ/FkUfCHqINRejR63QDVwvYGRPnrlg0c8rNiLDjfVyY83ESSqXN1hf/vzyVtGruj4t/35VsFL/fyE/iNGDDmMu/GH5Gbsa9+lykeRSOL97VAlzAuVeb4AwvZ9HFV5QcbGnNkrVG8sTMIOcUzJVGX2C38fnElGxGwrbpV8+ReMZtcQZSg2isRRKDUFRBdFFUrHKK8uqII+a5oZDi5OK7ytZHg8XTbrpJXStYhQjRMfbHsd2YFGeiyLWqzrASd/bpgdyLtZuQ1/r7z1IVGJjb01nNhD4mchU3Lj4mxaQe2zvBEhbUZufz2zrIDPiKxsQvYcqw4nvHJE7zWM0cMgHvQrzcZH44sHVtdVavjSPoOzN6665zaA9sCcYffESCPPQTnopE='
|
15
|
-
|
16
|
-
services:
|
17
|
-
- redis-server
|
18
|
-
|
19
|
-
before_script:
|
20
|
-
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
21
|
-
- chmod +x ./cc-test-reporter
|
22
|
-
- ./cc-test-reporter before-build
|
23
|
-
|
24
|
-
script:
|
25
|
-
- bin/rubocop
|
26
|
-
- bin/rspec --format doc
|
27
|
-
- bin/check-version
|
28
|
-
|
29
|
-
after_script:
|
30
|
-
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
31
|
-
|
32
|
-
jobs:
|
33
|
-
include:
|
34
|
-
- stage: release
|
35
|
-
rvm: 2.7
|
36
|
-
script: skip
|
37
|
-
deploy:
|
38
|
-
provider: rubygems
|
39
|
-
api_key:
|
40
|
-
secure: 'eS6u+XyT6hHk/0gLXWzoe3RTJzEVFQHcJ+MNGSp7iq+cavJHisndcYBmUxi6/Ttb/aT/YoczhIWYo6WPbcjDqWszDfUsrQyaiOiZy4BBcMwN1WHeHkeRHfO2NX7us0AKO66TAiNfpMqUR2UT/c1LCPtLb+bkG6IFWxRuF5Fo32e0th6Z+hJ4Se2E/Qg1lrZk5zBlhQSOtU88vWQAkT9FdzpwBskVENBuDmH5YTV2Y28QYHsDtSNIxoDiUK9LOoPxaYUQp5ZZ58HZHtPdNydPHvtOXaWcBlakH5HNkh3FUHsxqbA1b3U412PC4TK+0jnxfISH4EOAMZEkL1nmroJORlb5nlwG1eiHpPVbOke1z2cZarGmWWAEf9bGE99GVbuxUxRrm9i1rmPdJY2G6Z0Kz8zoLTDYI/9l2P81/99a7h84rWACeeI3bcdvqViLxUuVMiwQjQsOZhzfq1M6jjETAWAI3AMRLxaGSgp0LV3WtaSWk1T5qvOvOF2HIfQ1EMd74kblJrVGWUiqd94/UgQoB/+lg9PdP/h4aHY5Cq1ec83wzaO6leKNlO+EQfyAVD1nd8kxo7YHEUpcB8wWCNFA5iaLqwIMt7aeWvG/BVUIH0apppzJGDy9UZ0gGsYi6ID3gbRRgmHIdJospr6TN7hksu1ZqkwEaprpXq8zH0KFYW0='
|
41
|
-
gem: faulty
|
42
|
-
on:
|
43
|
-
tags: true
|
44
|
-
repo: ParentSquare/faulty
|
data/lib/faulty/scope.rb
DELETED
@@ -1,117 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Faulty
|
4
|
-
# A {Scope} is a group of options and circuits
|
5
|
-
#
|
6
|
-
# For most use-cases the default scope should be used, however, it's possible
|
7
|
-
# to create any number of scopes for applications that require a more complex
|
8
|
-
# configuration or for testing.
|
9
|
-
#
|
10
|
-
# For the most part, scopes are independent, however for some cache and
|
11
|
-
# storage backends, you will need to ensure that the cache keys and circuit
|
12
|
-
# names don't overlap between scopes. For example, if using the Redis storage
|
13
|
-
# backend, you should specify different key prefixes for each scope.
|
14
|
-
class Scope
|
15
|
-
attr_reader :options
|
16
|
-
|
17
|
-
# Options for {Scope}
|
18
|
-
#
|
19
|
-
# @!attribute [r] cache
|
20
|
-
# @return [Cache::Interface] A cache backend if you want
|
21
|
-
# to use Faulty's cache support. Automatically wrapped in a
|
22
|
-
# {Cache::FaultTolerantProxy}. Default `Cache::Default.new`.
|
23
|
-
# @!attribute [r] storage
|
24
|
-
# @return [Storage::Interface] The storage backend.
|
25
|
-
# Automatically wrapped in a {Storage::FaultTolerantProxy}.
|
26
|
-
# Default `Storage::Memory.new`.
|
27
|
-
# @!attribute [r] listeners
|
28
|
-
# @return [Array] listeners Faulty event listeners
|
29
|
-
# @!attribute [r] notifier
|
30
|
-
# @return [Events::Notifier] A Faulty notifier. If given, listeners are
|
31
|
-
# ignored.
|
32
|
-
Options = Struct.new(
|
33
|
-
:cache,
|
34
|
-
:storage,
|
35
|
-
:listeners,
|
36
|
-
:notifier
|
37
|
-
) do
|
38
|
-
include ImmutableOptions
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def finalize
|
43
|
-
self.notifier ||= Events::Notifier.new(listeners || [])
|
44
|
-
|
45
|
-
self.storage ||= Storage::Memory.new
|
46
|
-
unless storage.fault_tolerant?
|
47
|
-
self.storage = Storage::FaultTolerantProxy.new(storage, notifier: notifier)
|
48
|
-
end
|
49
|
-
|
50
|
-
self.cache ||= Cache::Default.new
|
51
|
-
unless cache.fault_tolerant?
|
52
|
-
self.cache = Cache::FaultTolerantProxy.new(cache, notifier: notifier)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def required
|
57
|
-
%i[cache storage notifier]
|
58
|
-
end
|
59
|
-
|
60
|
-
def defaults
|
61
|
-
{
|
62
|
-
listeners: [Events::LogListener.new]
|
63
|
-
}
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
# Create a new Faulty Scope
|
68
|
-
#
|
69
|
-
# Note, the process of creating a new scope is not thread safe,
|
70
|
-
# so make sure scopes are setup before spawning threads.
|
71
|
-
#
|
72
|
-
# @see Options
|
73
|
-
# @param options [Hash] Attributes for {Options}
|
74
|
-
# @yield [Options] For setting options in a block
|
75
|
-
def initialize(**options, &block)
|
76
|
-
@circuits = Concurrent::Map.new
|
77
|
-
@options = Options.new(options, &block)
|
78
|
-
end
|
79
|
-
|
80
|
-
# Create or retrieve a circuit
|
81
|
-
#
|
82
|
-
# Within a scope, circuit instances have unique names, so if the given circuit
|
83
|
-
# name already exists, then the existing circuit will be returned, otherwise
|
84
|
-
# a new circuit will be created. If an existing circuit is returned, then
|
85
|
-
# the {options} param and block are ignored.
|
86
|
-
#
|
87
|
-
# @param name [String] The name of the circuit
|
88
|
-
# @param options [Hash] Attributes for {Circuit::Options}
|
89
|
-
# @yield [Circuit::Options] For setting options in a block
|
90
|
-
# @return [Circuit] The new circuit or the existing circuit if it already exists
|
91
|
-
def circuit(name, **options, &block)
|
92
|
-
name = name.to_s
|
93
|
-
options = options.merge(circuit_options)
|
94
|
-
@circuits.compute_if_absent(name) do
|
95
|
-
Circuit.new(name, **options, &block)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
# Get a list of all circuit names
|
100
|
-
#
|
101
|
-
# @return [Array<String>] The circuit names
|
102
|
-
def list_circuits
|
103
|
-
options.storage.list
|
104
|
-
end
|
105
|
-
|
106
|
-
private
|
107
|
-
|
108
|
-
# Get circuit options from the scope options
|
109
|
-
#
|
110
|
-
# @return [Hash] The circuit options
|
111
|
-
def circuit_options
|
112
|
-
options = @options.to_h
|
113
|
-
options.delete(:listeners)
|
114
|
-
options
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|