always 0.0.2 → 0.0.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: 1d5c02ea320168984342dcf8805da07bec45d9a685097400c9f3e406a75a96b9
4
- data.tar.gz: 0db1ae1c2006db2de79982172f8fd7cc1d53e3fb8dfaffc8e474ea5972139224
3
+ metadata.gz: 915799402627806352f8d56f7050ae8c42ea03c9946eb60d46a983c1a0a7a13e
4
+ data.tar.gz: 5619766648e561e87b3df2dd07836b38a299d2d20b997bceee1df55a1db11e46
5
5
  SHA512:
6
- metadata.gz: 628d7ddcbc48d5e1b87adcccb7446a60c0ec1b4f1e047ee85b9a3188f76e3dbd42de40d384fc7e4f84de21c750ba26312b136d63a1248b575a1d3c2d68430a0a
7
- data.tar.gz: d9e259a904b1785543bb0282f026b0ee08e7ec1b641ee2243bd23d063a99df90b9dc69c69438f6d36f09bc7351a893b32581d0f475b7761d9997d7f112afa75a
6
+ metadata.gz: 50a3a60c35527a9f4d442f1c36ae79074cfc91d980eb0e530dfe092e1ffbcefc25ce879184d4ddf2fec76a1d02222eb484b40c4fb43f1de5a9eaf4a6b1181dd4
7
+ data.tar.gz: f006db78431ce7293bd8ed4d0d2f851dc9fb2f5cb475fa499af9dcad842a031b3c544046e4e0aa302ef59a9359e6540eb9a6c03b4a7db617be98f22670effbe0
data/.rubocop.yml CHANGED
@@ -27,3 +27,6 @@ AllCops:
27
27
  TargetRubyVersion: 3.2
28
28
  SuggestExtensions: false
29
29
  NewCops: enable
30
+
31
+ Layout/EndOfLine:
32
+ EnforcedStyle: lf
data/always.gemspec CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
26
26
  s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
27
27
  s.required_ruby_version = '>=3.2'
28
28
  s.name = 'always'
29
- s.version = '0.0.2'
29
+ s.version = '0.0.4'
30
30
  s.license = 'MIT'
31
31
  s.summary = 'A simple Ruby framework that spins a loop forever, in a background thread'
32
32
  s.description =
data/lib/always.rb CHANGED
@@ -44,7 +44,7 @@ require 'concurrent/atom'
44
44
  # License:: MIT
45
45
  class Always
46
46
  # The version of the framework.
47
- VERSION = '0.0.2'
47
+ VERSION = '0.0.4'
48
48
 
49
49
  # Constructor.
50
50
  # @param [Integer] total The number of threads to run
@@ -78,21 +78,27 @@ class Always
78
78
 
79
79
  # Start them all.
80
80
  # @param [Integer] pause The delay between cycles, in seconds
81
- def start(pause = 0)
81
+ def start(pause = 0, &)
82
82
  raise 'It is running now, call .stop() first' unless @threads.empty?
83
83
 
84
84
  (0..@total - 1).each do |i|
85
85
  @threads[i] = Thread.new do
86
- body(i, pause)
87
- @cycles.swap { |c| c + 1 }
86
+ body(pause, &)
88
87
  end
89
88
  end
90
89
  end
91
90
 
92
91
  # Stop them all.
93
92
  def stop
94
- @threads.each(&:terminate)
95
- @threads = []
93
+ raise 'It is not running now, call .start() first' if @threads.empty?
94
+
95
+ @threads.delete_if do |t|
96
+ t.kill
97
+ sleep(0.001) while t.alive?
98
+ true
99
+ end
100
+ @cycles.swap { |_| 0 }
101
+ @errors.swap { |_| 0 }
96
102
  end
97
103
 
98
104
  # Represent its internal state as a string.
@@ -106,15 +112,11 @@ class Always
106
112
  private
107
113
 
108
114
  # rubocop:disable Lint/RescueException
109
- def body(idx, pause)
115
+ def body(pause, &)
110
116
  loop do
111
- begin
112
- yield
113
- rescue Exception => e
114
- @errors.swap { |c| c + 1 }
115
- @on_error&.call(e, idx)
116
- end
117
- sleep(pause)
117
+ one(&)
118
+ @cycles.swap { |c| c + 1 }
119
+ sleep(pause) unless pause.zero?
118
120
  rescue Exception
119
121
  # If we reach this point, we must not even try to
120
122
  # do anything. Here we must quietly ignore everything
@@ -122,4 +124,13 @@ class Always
122
124
  end
123
125
  end
124
126
  # rubocop:enable Lint/RescueException
127
+
128
+ # rubocop:disable Lint/RescueException
129
+ def one
130
+ yield
131
+ rescue Exception => e
132
+ @errors.swap { |c| c + 1 }
133
+ @on_error&.call(e)
134
+ end
135
+ # rubocop:enable Lint/RescueException
125
136
  end
data/test/test_always.rb CHANGED
@@ -39,7 +39,7 @@ class TestAlways < Minitest::Test
39
39
  def test_with_error
40
40
  a = Always.new(5)
41
41
  failures = 0
42
- a.on_error { |_e, i| failures += i }.start do
42
+ a.on_error { |_e| failures += 1 }.start do
43
43
  raise 'intentionally'
44
44
  end
45
45
  sleep(0.1)
@@ -48,11 +48,33 @@ class TestAlways < Minitest::Test
48
48
  end
49
49
 
50
50
  def test_converts_to_string
51
- a = Always.new(5)
51
+ n = 6
52
+ a = Always.new(6)
53
+ a.start { sleep(0.01) }
54
+ sleep(0.1)
55
+ threads, cycles, errors = a.to_s.split('/')
56
+ assert_equal(n, threads.to_i)
57
+ assert(cycles.to_i.positive?)
58
+ assert(errors.to_i.zero?)
59
+ a.stop
60
+ end
61
+
62
+ def test_stops_correctly
63
+ a = Always.new(6)
64
+ a.start { sleep(0.01) }
65
+ sleep(0.01)
66
+ a.stop
67
+ assert_equal('0/0/0', a.to_s)
68
+ end
69
+
70
+ def test_with_counter
71
+ a = Always.new(1)
72
+ done = 0
52
73
  a.start do
53
- # nothing
74
+ done += 1
54
75
  end
55
- assert(a.to_s.start_with?('5/'))
76
+ sleep(0.1)
56
77
  a.stop
78
+ assert(done.positive?)
57
79
  end
58
80
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: always
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko