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 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: []