forked 0.1.2 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d65e9b3c269236fd1f7faeddbe8c8796525fab8aa14f6ba3be17030170fbd4b9
4
- data.tar.gz: ee017ee80e792ca9430d7b9ce63b463d51b133417fe2c36ee91642d186dedf25
3
+ metadata.gz: 38857b0c3e238d585fc5dee12ef826e4015cc746eabc81f3d05eddecf29ee9a9
4
+ data.tar.gz: 83a3e12ceaeedfb96a2023231097162f27e1d75c5c97cadfd8beb9c16e718b19
5
5
  SHA512:
6
- metadata.gz: b50f13ede5e8aea35fdc389b0f9f58f7aec2f65d2c2794fa2d6b39bd2b75ad36527846c48ebf13dd253333dc97bea0360a57e7febf632d4e026c68484ed4892f
7
- data.tar.gz: 29c79019463de9c4cf9b9b070387c8dfd6920273a383348934dff84e1078b5cf9f36f6ffb711fcbf1fc764640e925ed0e3b2bb4fb37eab314f6eb4944a9f07bb
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.2)
4
+ forked (0.1.4)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- coderay (1.1.2)
10
- diff-lcs (1.3)
11
- method_source (0.9.0)
12
- pry (0.11.3)
13
- coderay (~> 1.1.0)
14
- method_source (~> 0.9.0)
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.7.0)
17
- rspec-core (~> 3.7.0)
18
- rspec-expectations (~> 3.7.0)
19
- rspec-mocks (~> 3.7.0)
20
- rspec-core (3.7.0)
21
- rspec-support (~> 3.7.0)
22
- rspec-expectations (3.7.0)
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.7.0)
25
- rspec-mocks (3.7.0)
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.7.0)
28
- rspec-support (3.7.0)
27
+ rspec-support (~> 3.12.0)
28
+ rspec-support (3.12.0)
29
29
 
30
30
  PLATFORMS
31
- ruby
31
+ arm64-darwin-21
32
32
 
33
33
  DEPENDENCIES
34
- bundler (~> 1.15)
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
- 1.17.1
41
+ 2.3.26
data/README.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Forked
2
2
 
3
+ [![License MIT](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://github.com/envato/forked/blob/master/LICENSE.txt)
4
+ [![Gem Version](https://img.shields.io/gem/v/forked.svg?maxAge=2592000)](https://rubygems.org/gems/forked)
5
+ [![Gem Downloads](https://img.shields.io/gem/dt/forked.svg?maxAge=2592000)](https://rubygems.org/gems/forked)
6
+ [![Test Suite](https://github.com/envato/forked/workflows/tests/badge.svg?branch=master)](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
- process_manager.fork('monitor', on_error: ->(e, tries) { puts e.inspect }) do
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
- puts "hi"
24
- sleep 1
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 # triggers a shutdown if a TERM/INT signal has been received
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(name, retry_strategy, on_error, block)
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
- retry_strategy = worker.retry_strategy.new(logger: @logger, on_error: worker.on_error)
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
@@ -1,3 +1,3 @@
1
1
  module Forked
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.4"
3
3
  end
data/lib/forked/worker.rb CHANGED
@@ -1,4 +1,10 @@
1
1
  module Forked
2
- class Worker < Struct.new(:name, :retry_strategy, :on_error, :block)
2
+ class Worker < Struct.new(
3
+ :name,
4
+ :retry_strategy,
5
+ :retry_backoff_limit,
6
+ :on_error,
7
+ :block,
8
+ keyword_init: true)
3
9
  end
4
10
  end
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.2
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: 2018-12-18 00:00:00.000000000 Z
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.15'
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.15'
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
- rubyforge_project:
107
- rubygems_version: 2.7.6
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: []