respawn 0.1.3 → 0.1.4
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/lib/respawn/exception_detector.rb +38 -0
- data/lib/respawn/handler.rb +32 -0
- data/lib/respawn/notifier_detector.rb +31 -0
- data/lib/respawn/predicate.rb +4 -0
- data/lib/respawn/setup.rb +10 -0
- data/lib/respawn/try.rb +15 -45
- data/lib/respawn/version.rb +1 -1
- data/lib/respawn.rb +18 -4
- metadata +20 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b9ce4db696ee967e602013fa85f37caf81b7bff5afa2fb7af1b12c6ba548a336
|
4
|
+
data.tar.gz: 9461debe887911b3256159d94fe156d89e1c0c10e80f3e30f2fbbef18bb7ddb3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c11d9f8166b63a5e2f73f856b8fbff47104159e9ef2be89ca9914d5bf5ea8a52d85a996f49ed9016082ac35074970aa7427b9dd399ea755090fcb39d9d817810
|
7
|
+
data.tar.gz: 2c5264cfe13032166e06e4c6d6f009399f487b44c27dfa6766e66e231a958f7007c0bb685bafb42ae47309ce93d053d179d4e0a0509f55d74b3b8d4ceb99426e
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Respawn
|
4
|
+
class ExceptionDetector
|
5
|
+
PREDEFINED_EXCEPTIONS = [
|
6
|
+
EOFError,
|
7
|
+
Errno::ECONNABORTED,
|
8
|
+
Errno::ECONNRESET,
|
9
|
+
Errno::EHOSTUNREACH,
|
10
|
+
].freeze
|
11
|
+
|
12
|
+
DYNAMIC_EXCEPTIONS = [
|
13
|
+
"SocketError",
|
14
|
+
"Faraday::ConnectionFailed",
|
15
|
+
"Faraday::TimeoutError",
|
16
|
+
"Faraday::ClientError",
|
17
|
+
"Faraday::ServerError",
|
18
|
+
"Net::OpenTimeout",
|
19
|
+
"Net::ReadTimeout",
|
20
|
+
"OpenSSL::SSL::SSLError",
|
21
|
+
"OpenURI::HTTPError",
|
22
|
+
].freeze
|
23
|
+
|
24
|
+
def self.call(...)
|
25
|
+
new(...).call
|
26
|
+
end
|
27
|
+
|
28
|
+
def call
|
29
|
+
PREDEFINED_EXCEPTIONS + dynamic_exceptions
|
30
|
+
end
|
31
|
+
|
32
|
+
def dynamic_exceptions
|
33
|
+
DYNAMIC_EXCEPTIONS.filter_map do
|
34
|
+
Object.const_get(it) if Object.const_defined?(it)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Respawn
|
2
|
+
class Handler
|
3
|
+
def initialize(onfail)
|
4
|
+
self.onfail = onfail
|
5
|
+
self.retry_number = 0
|
6
|
+
# self.predicates = []
|
7
|
+
end
|
8
|
+
|
9
|
+
# def predicate(&block)
|
10
|
+
# self.predicates << block
|
11
|
+
# end
|
12
|
+
|
13
|
+
def define(&block)
|
14
|
+
return if self.block
|
15
|
+
|
16
|
+
if onfail != :handler
|
17
|
+
raise Try::Error, "Cannot define a block unless onfail is :handler"
|
18
|
+
end
|
19
|
+
|
20
|
+
self.block = block
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_accessor :onfail, :retry_number
|
24
|
+
|
25
|
+
attr_reader :block
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_accessor :onfail, :predicates
|
30
|
+
attr_writer :block
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Respawn
|
4
|
+
class NotifierDetector
|
5
|
+
def self.call(...)
|
6
|
+
new(...).call
|
7
|
+
end
|
8
|
+
|
9
|
+
def call
|
10
|
+
detect_notifier
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def detect_notifier
|
16
|
+
if defined?(TestNotifier)
|
17
|
+
TestNotifier.method(:call)
|
18
|
+
elsif defined?(::Sentry)
|
19
|
+
Sentry.method(:capture_exception)
|
20
|
+
elsif defined?(::Airbrake)
|
21
|
+
:airbrake
|
22
|
+
elsif defined?(::Bugsnag)
|
23
|
+
:bugsnag
|
24
|
+
elsif defined?(::Rollbar)
|
25
|
+
:rollbar
|
26
|
+
else
|
27
|
+
proc {}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/respawn/try.rb
CHANGED
@@ -6,22 +6,6 @@ module Respawn
|
|
6
6
|
class Try
|
7
7
|
class Error < StandardError; end
|
8
8
|
|
9
|
-
COMMON_NETWORK_EXCEPTIONS = [
|
10
|
-
EOFError,
|
11
|
-
defined?(SocketError) && SocketError,
|
12
|
-
Errno::ECONNABORTED,
|
13
|
-
Errno::ECONNRESET,
|
14
|
-
Errno::EHOSTUNREACH,
|
15
|
-
# Faraday::ConnectionFailed,
|
16
|
-
# Faraday::TimeoutError,
|
17
|
-
# Faraday::ClientError,
|
18
|
-
# Faraday::ServerError,
|
19
|
-
# Net::OpenTimeout,
|
20
|
-
# Net::ReadTimeout,
|
21
|
-
# OpenSSL::SSL::SSLError,
|
22
|
-
# OpenURI::HTTPError,
|
23
|
-
].compact.freeze
|
24
|
-
|
25
9
|
ONFAIL = [
|
26
10
|
:notify,
|
27
11
|
:nothing,
|
@@ -29,37 +13,31 @@ module Respawn
|
|
29
13
|
:handler,
|
30
14
|
].freeze
|
31
15
|
|
32
|
-
class Handler
|
33
|
-
attr_accessor :block
|
34
|
-
|
35
|
-
def define(&block)
|
36
|
-
self.block = block
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
class NullHandler
|
41
|
-
def define(&)
|
42
|
-
raise Error, "Cannot define a block unless onfail is :handler"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
16
|
def self.call(*, **, &)
|
47
17
|
new(*, **).call(&)
|
48
18
|
end
|
49
19
|
|
50
|
-
def initialize(*exceptions, tries: 5, onfail: :notify, wait: 0.5, env: nil)
|
51
|
-
self.
|
20
|
+
def initialize(*exceptions, predicate: [], tries: 5, onfail: :notify, wait: 0.5, env: nil)
|
21
|
+
self.predicate = predicate
|
22
|
+
self.exceptions = parse_exceptions(exceptions) + [PredicateError]
|
52
23
|
self.tries = tries
|
53
24
|
self.onfail = ONFAIL.zip(ONFAIL).to_h.fetch(onfail)
|
54
25
|
self.wait = wait
|
55
|
-
self.handler =
|
26
|
+
self.handler = Handler.new(onfail)
|
56
27
|
self.env = env || Environment.new(default_environment)
|
57
28
|
end
|
58
29
|
|
59
30
|
def call
|
60
|
-
yield(handler)
|
31
|
+
yield(handler).tap do |result|
|
32
|
+
Array(predicate).each.with_index do |condition, index|
|
33
|
+
if condition.call(result)
|
34
|
+
raise PredicateError, "Predicate #{condition.inspect} matched the result"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
61
38
|
rescue *exceptions => e
|
62
39
|
self.tries = tries - 1
|
40
|
+
handler.retry_number += 1
|
63
41
|
|
64
42
|
if tries.positive?
|
65
43
|
Kernel.sleep(wait) unless env.test?
|
@@ -71,7 +49,7 @@ module Respawn
|
|
71
49
|
|
72
50
|
private
|
73
51
|
|
74
|
-
attr_accessor :exceptions, :tries, :onfail, :wait, :handler, :env
|
52
|
+
attr_accessor :exceptions, :tries, :onfail, :wait, :handler, :env, :predicate
|
75
53
|
|
76
54
|
def default_environment
|
77
55
|
ENV.fetch("RUBY_ENV") do
|
@@ -81,18 +59,10 @@ module Respawn
|
|
81
59
|
end
|
82
60
|
end
|
83
61
|
|
84
|
-
def handler_for(onfail)
|
85
|
-
if onfail == :handler
|
86
|
-
Handler.new
|
87
|
-
else
|
88
|
-
NullHandler.new
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
62
|
def perform_fail(exception)
|
93
63
|
case onfail
|
94
64
|
in :notify
|
95
|
-
|
65
|
+
Respawn.default_setup.notifier.call(exception)
|
96
66
|
in :nothing
|
97
67
|
nil
|
98
68
|
in :raise
|
@@ -105,7 +75,7 @@ module Respawn
|
|
105
75
|
def parse_exceptions(list)
|
106
76
|
list.flat_map do |exception|
|
107
77
|
if exception == :network_errors
|
108
|
-
|
78
|
+
Respawn.default_setup.cause
|
109
79
|
|
110
80
|
# This comparision will raise an error if the exception is not
|
111
81
|
# a class, which is what we want.
|
data/lib/respawn/version.rb
CHANGED
data/lib/respawn.rb
CHANGED
@@ -2,14 +2,28 @@
|
|
2
2
|
|
3
3
|
require "zeitwerk"
|
4
4
|
|
5
|
+
loader = Zeitwerk::Loader.for_gem
|
6
|
+
loader.setup
|
7
|
+
loader.eager_load
|
8
|
+
|
5
9
|
module Respawn
|
6
10
|
class Error < StandardError; end
|
11
|
+
class PredicateError < StandardError; end
|
7
12
|
|
8
13
|
def self.try(...)
|
9
14
|
Try.call(...)
|
10
15
|
end
|
11
|
-
end
|
12
16
|
|
13
|
-
|
14
|
-
|
15
|
-
|
17
|
+
# Postpone the actuall setup until the first use of the method, to make
|
18
|
+
# sure that all the dependencies are loaded and all constants are already
|
19
|
+
# available.
|
20
|
+
|
21
|
+
def self.default_setup
|
22
|
+
@_default_setup ||=
|
23
|
+
Setup.new(
|
24
|
+
notifier: NotifierDetector.call,
|
25
|
+
cause: ExceptionDetector.call,
|
26
|
+
predicate: [],
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: respawn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mariusz Drozdziel
|
@@ -9,6 +9,20 @@ bindir: bin
|
|
9
9
|
cert_chain: []
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: pry
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - "~>"
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '0.15'
|
19
|
+
type: :development
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - "~>"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '0.15'
|
12
26
|
- !ruby/object:Gem::Dependency
|
13
27
|
name: rspec
|
14
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,6 +58,11 @@ extensions: []
|
|
44
58
|
extra_rdoc_files: []
|
45
59
|
files:
|
46
60
|
- lib/respawn.rb
|
61
|
+
- lib/respawn/exception_detector.rb
|
62
|
+
- lib/respawn/handler.rb
|
63
|
+
- lib/respawn/notifier_detector.rb
|
64
|
+
- lib/respawn/predicate.rb
|
65
|
+
- lib/respawn/setup.rb
|
47
66
|
- lib/respawn/try.rb
|
48
67
|
- lib/respawn/version.rb
|
49
68
|
homepage: https://github.com/marzdrel/respawn
|