respawn 0.1.3 → 0.1.5
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 +18 -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: cde24c2f311c9468a6b9811fcc531c029b1d8addfee5e7a9b5c6283ca86e9cf3
|
4
|
+
data.tar.gz: dab8ea8a99e90ef941cdce690fa2dad567351c289ad6d50a1bd7b65c325651b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cee1d10a076206759a165f991bd1c8fec776e453a3525f55c44118b3939190da1acb87e949b7f6e6d4d36846281b5e6d1cbf6cb0194796adf58dd7e22d65bc06
|
7
|
+
data.tar.gz: 54226cd2b318a05554bb1f7c8e9707894f50f5bf9587c19ef29389a4406864c68a786f85761ca0ba2436cc1938503a8d3eb9c5b23f044cacbdd705a99b2fb6b1
|
@@ -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,34 @@ 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(
|
35
|
+
PredicateError,
|
36
|
+
"Predicate ##{index} matched (#{condition.inspect})",
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
61
41
|
rescue *exceptions => e
|
62
42
|
self.tries = tries - 1
|
43
|
+
handler.retry_number += 1
|
63
44
|
|
64
45
|
if tries.positive?
|
65
46
|
Kernel.sleep(wait) unless env.test?
|
@@ -71,7 +52,7 @@ module Respawn
|
|
71
52
|
|
72
53
|
private
|
73
54
|
|
74
|
-
attr_accessor :exceptions, :tries, :onfail, :wait, :handler, :env
|
55
|
+
attr_accessor :exceptions, :tries, :onfail, :wait, :handler, :env, :predicate
|
75
56
|
|
76
57
|
def default_environment
|
77
58
|
ENV.fetch("RUBY_ENV") do
|
@@ -81,18 +62,10 @@ module Respawn
|
|
81
62
|
end
|
82
63
|
end
|
83
64
|
|
84
|
-
def handler_for(onfail)
|
85
|
-
if onfail == :handler
|
86
|
-
Handler.new
|
87
|
-
else
|
88
|
-
NullHandler.new
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
65
|
def perform_fail(exception)
|
93
66
|
case onfail
|
94
67
|
in :notify
|
95
|
-
|
68
|
+
Respawn.default_setup.notifier.call(exception)
|
96
69
|
in :nothing
|
97
70
|
nil
|
98
71
|
in :raise
|
@@ -105,7 +78,7 @@ module Respawn
|
|
105
78
|
def parse_exceptions(list)
|
106
79
|
list.flat_map do |exception|
|
107
80
|
if exception == :network_errors
|
108
|
-
|
81
|
+
Respawn.default_setup.cause
|
109
82
|
|
110
83
|
# This comparision will raise an error if the exception is not
|
111
84
|
# 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.5
|
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
|