forked 0.1.2 → 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/Gemfile.lock +21 -21
- data/README.md +24 -4
- data/forked.gemspec +28 -0
- data/lib/forked/process_manager.rb +12 -3
- data/lib/forked/retry_strategies/exponential_backoff_with_limit.rb +33 -0
- data/lib/forked/version.rb +1 -1
- data/lib/forked/worker.rb +7 -1
- data/lib/forked.rb +1 -0
- metadata +10 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 38857b0c3e238d585fc5dee12ef826e4015cc746eabc81f3d05eddecf29ee9a9
|
4
|
+
data.tar.gz: 83a3e12ceaeedfb96a2023231097162f27e1d75c5c97cadfd8beb9c16e718b19
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e828c5610cb58ef373c4e3384e83c5f55d3ba744d364ec91eddf3e7839feda8c837cc050815613db145f66e53e25d3e81c843b27792c02d5468cbd37936fff2e
|
7
|
+
data.tar.gz: 187b9ed0ec291b52236093055818042fb723b5a4708690080ba72b6607cdf574eeb60487df76437b753464615f4e67fba3b2ebf38af65107bb5f7794469ba989
|
data/Gemfile.lock
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
forked (0.1.
|
4
|
+
forked (0.1.4)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
-
coderay (1.1.
|
10
|
-
diff-lcs (1.
|
11
|
-
method_source (0.
|
12
|
-
pry (0.
|
13
|
-
coderay (~> 1.1
|
14
|
-
method_source (~>
|
9
|
+
coderay (1.1.3)
|
10
|
+
diff-lcs (1.5.0)
|
11
|
+
method_source (1.0.0)
|
12
|
+
pry (0.14.1)
|
13
|
+
coderay (~> 1.1)
|
14
|
+
method_source (~> 1.0)
|
15
15
|
rake (10.5.0)
|
16
|
-
rspec (3.
|
17
|
-
rspec-core (~> 3.
|
18
|
-
rspec-expectations (~> 3.
|
19
|
-
rspec-mocks (~> 3.
|
20
|
-
rspec-core (3.
|
21
|
-
rspec-support (~> 3.
|
22
|
-
rspec-expectations (3.
|
16
|
+
rspec (3.12.0)
|
17
|
+
rspec-core (~> 3.12.0)
|
18
|
+
rspec-expectations (~> 3.12.0)
|
19
|
+
rspec-mocks (~> 3.12.0)
|
20
|
+
rspec-core (3.12.0)
|
21
|
+
rspec-support (~> 3.12.0)
|
22
|
+
rspec-expectations (3.12.2)
|
23
23
|
diff-lcs (>= 1.2.0, < 2.0)
|
24
|
-
rspec-support (~> 3.
|
25
|
-
rspec-mocks (3.
|
24
|
+
rspec-support (~> 3.12.0)
|
25
|
+
rspec-mocks (3.12.2)
|
26
26
|
diff-lcs (>= 1.2.0, < 2.0)
|
27
|
-
rspec-support (~> 3.
|
28
|
-
rspec-support (3.
|
27
|
+
rspec-support (~> 3.12.0)
|
28
|
+
rspec-support (3.12.0)
|
29
29
|
|
30
30
|
PLATFORMS
|
31
|
-
|
31
|
+
arm64-darwin-21
|
32
32
|
|
33
33
|
DEPENDENCIES
|
34
|
-
bundler (~> 1
|
34
|
+
bundler (~> 2.1)
|
35
35
|
forked!
|
36
36
|
pry
|
37
37
|
rake (~> 10.0)
|
38
38
|
rspec (~> 3.0)
|
39
39
|
|
40
40
|
BUNDLED WITH
|
41
|
-
|
41
|
+
2.3.26
|
data/README.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Forked
|
2
2
|
|
3
|
+
[](https://github.com/envato/forked/blob/master/LICENSE.txt)
|
4
|
+
[](https://rubygems.org/gems/forked)
|
5
|
+
[](https://rubygems.org/gems/forked)
|
6
|
+
[](https://github.com/envato/forked/actions?query=branch%3Amaster+workflow%3Atests)
|
7
|
+
|
3
8
|
Forked manages long running worker processes.
|
4
9
|
|
5
10
|
Processes that crash are restarted, whereas processes that exit successfully
|
@@ -18,16 +23,31 @@ require 'forked'
|
|
18
23
|
|
19
24
|
process_manager = Forked::ProcessManager.new(logger: Logger.new(STDOUT), process_timeout: 5)
|
20
25
|
|
21
|
-
|
26
|
+
# Default retry_strategy = Forked::RetryStrategies::Always
|
27
|
+
# Calling `ready_to_stop` within the loop ensures a shutdown is triggered if a TERM/INT signal is received
|
28
|
+
process_manager.fork('monitor', on_error: ->(e, tries) { puts e.inspect }) do |ready_to_stop|
|
22
29
|
loop do
|
23
|
-
|
24
|
-
|
30
|
+
ready_to_stop.call
|
31
|
+
# do something
|
25
32
|
end
|
26
33
|
end
|
27
34
|
|
35
|
+
# Using the ExponentialBackoff retry_strategy
|
36
|
+
# If there is an error, process_manager backs off for a time then restarts the loop
|
37
|
+
# The back off time increases as the number of errors increase
|
28
38
|
process_manager.fork('processor_1', retry_strategy: Forked::RetryStrategies::ExponentialBackoff) do |ready_to_stop|
|
29
39
|
loop do
|
30
|
-
ready_to_stop.call
|
40
|
+
ready_to_stop.call
|
41
|
+
# do something
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Using the ExponentialBackoffWithLimit retry_strategy
|
46
|
+
# Follows the ExponentialBackoff retry strategy, but if the error keeps occurring
|
47
|
+
# until a given limit (default: 8), the error bubbles up and the loop is not restarted
|
48
|
+
process_manager.fork('processor_1', retry_strategy: Forked::RetryStrategies::ExponentialBackoffWithLimit, retry_backoff_limit: 10) do |ready_to_stop|
|
49
|
+
loop do
|
50
|
+
ready_to_stop.call
|
31
51
|
# do something
|
32
52
|
end
|
33
53
|
end
|
data/forked.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "forked/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "forked"
|
8
|
+
spec.version = Forked::VERSION
|
9
|
+
spec.authors = ["Steve Hodgkiss"]
|
10
|
+
spec.email = ["steve@hodgkiss.me"]
|
11
|
+
|
12
|
+
spec.summary = %q{Manage long running forked processes}
|
13
|
+
spec.description = %q{}
|
14
|
+
spec.homepage = "https://github.com/envato/forked"
|
15
|
+
|
16
|
+
spec.files = Dir["lib/**/*.rb"]
|
17
|
+
spec.files += Dir['[A-Z]*']
|
18
|
+
spec.require_paths = ['lib']
|
19
|
+
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 2.1"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
27
|
+
spec.add_development_dependency "pry"
|
28
|
+
end
|
@@ -11,8 +11,14 @@ module Forked
|
|
11
11
|
@logger = logger
|
12
12
|
end
|
13
13
|
|
14
|
-
def fork(name = nil, retry_strategy: ::Forked::RetryStrategies::ExponentialBackoff, on_error: ON_ERROR, &block)
|
15
|
-
worker = Worker.new(
|
14
|
+
def fork(name = nil, retry_strategy: ::Forked::RetryStrategies::ExponentialBackoff, retry_backoff_limit: nil, on_error: ON_ERROR, &block)
|
15
|
+
worker = Worker.new(
|
16
|
+
name: name,
|
17
|
+
retry_strategy: retry_strategy,
|
18
|
+
retry_backoff_limit: retry_backoff_limit,
|
19
|
+
on_error: on_error,
|
20
|
+
block: block,
|
21
|
+
)
|
16
22
|
fork_worker(worker)
|
17
23
|
end
|
18
24
|
|
@@ -37,7 +43,10 @@ module Forked
|
|
37
43
|
private
|
38
44
|
|
39
45
|
def fork_worker(worker)
|
40
|
-
|
46
|
+
retry_params = { logger: @logger, on_error: worker.on_error }
|
47
|
+
retry_params[:limit] = worker.retry_backoff_limit if worker.retry_strategy == RetryStrategies::ExponentialBackoffWithLimit
|
48
|
+
retry_strategy = worker.retry_strategy.new(**retry_params)
|
49
|
+
|
41
50
|
pid = Kernel.fork do
|
42
51
|
WithGracefulShutdown.run(logger: @logger) do |ready_to_stop|
|
43
52
|
retry_strategy.run(ready_to_stop) do
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Forked
|
2
|
+
module RetryStrategies
|
3
|
+
class ExponentialBackoffWithLimit
|
4
|
+
def initialize(logger:, on_error:, backoff_factor: 2, limit: nil)
|
5
|
+
@logger = logger
|
6
|
+
@on_error = on_error
|
7
|
+
@backoff_factor = backoff_factor
|
8
|
+
@limit = limit || 8
|
9
|
+
end
|
10
|
+
|
11
|
+
def run(ready_to_stop, &block)
|
12
|
+
tries = 0
|
13
|
+
begin
|
14
|
+
block.call
|
15
|
+
rescue => e
|
16
|
+
tries += 1
|
17
|
+
|
18
|
+
@logger.error("#{e.class} #{e.message}")
|
19
|
+
@on_error.call(e, tries)
|
20
|
+
raise if tries > @limit
|
21
|
+
|
22
|
+
sleep_seconds = @backoff_factor**tries
|
23
|
+
sleep_seconds.times do
|
24
|
+
ready_to_stop.call
|
25
|
+
sleep 1
|
26
|
+
end
|
27
|
+
|
28
|
+
retry
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/forked/version.rb
CHANGED
data/lib/forked/worker.rb
CHANGED
data/lib/forked.rb
CHANGED
@@ -2,6 +2,7 @@ require 'forked/version'
|
|
2
2
|
require 'forked/worker'
|
3
3
|
require 'forked/retry_strategies/always'
|
4
4
|
require 'forked/retry_strategies/exponential_backoff'
|
5
|
+
require 'forked/retry_strategies/exponential_backoff_with_limit'
|
5
6
|
require 'forked/process_manager'
|
6
7
|
require 'forked/with_graceful_shutdown'
|
7
8
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: forked
|
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
|
- Steve Hodgkiss
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1
|
19
|
+
version: '2.1'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1
|
26
|
+
version: '2.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,17 +78,19 @@ files:
|
|
78
78
|
- LICENSE.txt
|
79
79
|
- README.md
|
80
80
|
- Rakefile
|
81
|
+
- forked.gemspec
|
81
82
|
- lib/forked.rb
|
82
83
|
- lib/forked/process_manager.rb
|
83
84
|
- lib/forked/retry_strategies/always.rb
|
84
85
|
- lib/forked/retry_strategies/exponential_backoff.rb
|
86
|
+
- lib/forked/retry_strategies/exponential_backoff_with_limit.rb
|
85
87
|
- lib/forked/version.rb
|
86
88
|
- lib/forked/with_graceful_shutdown.rb
|
87
89
|
- lib/forked/worker.rb
|
88
90
|
homepage: https://github.com/envato/forked
|
89
91
|
licenses: []
|
90
92
|
metadata: {}
|
91
|
-
post_install_message:
|
93
|
+
post_install_message:
|
92
94
|
rdoc_options: []
|
93
95
|
require_paths:
|
94
96
|
- lib
|
@@ -103,9 +105,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
105
|
- !ruby/object:Gem::Version
|
104
106
|
version: '0'
|
105
107
|
requirements: []
|
106
|
-
|
107
|
-
|
108
|
-
signing_key:
|
108
|
+
rubygems_version: 3.3.26
|
109
|
+
signing_key:
|
109
110
|
specification_version: 4
|
110
111
|
summary: Manage long running forked processes
|
111
112
|
test_files: []
|