always 0.0.4 → 0.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 915799402627806352f8d56f7050ae8c42ea03c9946eb60d46a983c1a0a7a13e
4
- data.tar.gz: 5619766648e561e87b3df2dd07836b38a299d2d20b997bceee1df55a1db11e46
3
+ metadata.gz: 3e58e6ba3b68a86d0f9fc12a7bc34580085f00b4511e5ea34167465338a51789
4
+ data.tar.gz: cac5d0bc4f8d7d16aff1ae095e4b204c431737603fa2a3be4245c10a44d0bb84
5
5
  SHA512:
6
- metadata.gz: 50a3a60c35527a9f4d442f1c36ae79074cfc91d980eb0e530dfe092e1ffbcefc25ce879184d4ddf2fec76a1d02222eb484b40c4fb43f1de5a9eaf4a6b1181dd4
7
- data.tar.gz: f006db78431ce7293bd8ed4d0d2f851dc9fb2f5cb475fa499af9dcad842a031b3c544046e4e0aa302ef59a9359e6540eb9a6c03b4a7db617be98f22670effbe0
6
+ metadata.gz: ec65e4cc308a110d2867ca647e197061b1811b15a09da8dd9e5e71259135808409c0e26d47c738d9e0c3187cf93050caec5779622cf9c5a8f14e895befaf18c9
7
+ data.tar.gz: 6fa3988429a11ef790c92715a23a9f31a4445ffd27fcbc5eaa8ecfd91d5d42f7c7da18d6ee18802d4f0000bd9c6b9ad86ee84a1a1e9e9c333e94a75633e48bd8
data/.rubocop.yml CHANGED
@@ -30,3 +30,5 @@ AllCops:
30
30
 
31
31
  Layout/EndOfLine:
32
32
  EnforcedStyle: lf
33
+ Style/EvalWithLocation:
34
+ Enabled: false
data/Gemfile CHANGED
@@ -23,11 +23,11 @@
23
23
  source 'https://rubygems.org'
24
24
  gemspec
25
25
 
26
- gem 'minitest', '5.23.1', require: false
26
+ gem 'minitest', '5.24.1', require: false
27
27
  gem 'rake', '13.2.1', require: false
28
- gem 'rspec-rails', '6.1.2', require: false
28
+ gem 'rspec-rails', '6.1.3', require: false
29
29
  gem 'rubocop', '1.64.1', require: false
30
- gem 'rubocop-rspec', '2.29.2', require: false
30
+ gem 'rubocop-rspec', '3.0.2', require: false
31
31
  gem 'simplecov', '0.22.0', require: false
32
32
  gem 'simplecov-cobertura', '2.1.0', require: false
33
33
  gem 'yard', '0.9.36', require: false
data/Gemfile.lock CHANGED
@@ -7,9 +7,9 @@ PATH
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- actionpack (7.1.3.3)
11
- actionview (= 7.1.3.3)
12
- activesupport (= 7.1.3.3)
10
+ actionpack (7.1.3.4)
11
+ actionview (= 7.1.3.4)
12
+ activesupport (= 7.1.3.4)
13
13
  nokogiri (>= 1.8.5)
14
14
  racc
15
15
  rack (>= 2.2.4)
@@ -17,13 +17,13 @@ GEM
17
17
  rack-test (>= 0.6.3)
18
18
  rails-dom-testing (~> 2.2)
19
19
  rails-html-sanitizer (~> 1.6)
20
- actionview (7.1.3.3)
21
- activesupport (= 7.1.3.3)
20
+ actionview (7.1.3.4)
21
+ activesupport (= 7.1.3.4)
22
22
  builder (~> 3.1)
23
23
  erubi (~> 1.11)
24
24
  rails-dom-testing (~> 2.2)
25
25
  rails-html-sanitizer (~> 1.6)
26
- activesupport (7.1.3.3)
26
+ activesupport (7.1.3.4)
27
27
  base64
28
28
  bigdecimal
29
29
  concurrent-ruby (~> 1.0, >= 1.0.2)
@@ -36,18 +36,18 @@ GEM
36
36
  ast (2.4.2)
37
37
  base64 (0.2.0)
38
38
  bigdecimal (3.1.8)
39
- builder (3.2.4)
40
- concurrent-ruby (1.3.1)
39
+ builder (3.3.0)
40
+ concurrent-ruby (1.3.3)
41
41
  connection_pool (2.4.1)
42
42
  crass (1.0.6)
43
43
  diff-lcs (1.5.1)
44
44
  docile (1.4.0)
45
45
  drb (2.2.1)
46
- erubi (1.12.0)
46
+ erubi (1.13.0)
47
47
  i18n (1.14.5)
48
48
  concurrent-ruby (~> 1.0)
49
49
  io-console (0.7.2)
50
- irb (1.13.1)
50
+ irb (1.13.2)
51
51
  rdoc (>= 4.0.0)
52
52
  reline (>= 0.4.2)
53
53
  json (2.7.2)
@@ -55,30 +55,30 @@ GEM
55
55
  loofah (2.22.0)
56
56
  crass (~> 1.0.2)
57
57
  nokogiri (>= 1.12.0)
58
- minitest (5.23.1)
58
+ minitest (5.24.1)
59
59
  mutex_m (0.2.0)
60
- nokogiri (1.16.5-aarch64-linux)
60
+ nokogiri (1.16.6-aarch64-linux)
61
61
  racc (~> 1.4)
62
- nokogiri (1.16.5-arm-linux)
62
+ nokogiri (1.16.6-arm-linux)
63
63
  racc (~> 1.4)
64
- nokogiri (1.16.5-arm64-darwin)
64
+ nokogiri (1.16.6-arm64-darwin)
65
65
  racc (~> 1.4)
66
- nokogiri (1.16.5-x64-mingw-ucrt)
66
+ nokogiri (1.16.6-x64-mingw-ucrt)
67
67
  racc (~> 1.4)
68
- nokogiri (1.16.5-x86-linux)
68
+ nokogiri (1.16.6-x86-linux)
69
69
  racc (~> 1.4)
70
- nokogiri (1.16.5-x86_64-darwin)
70
+ nokogiri (1.16.6-x86_64-darwin)
71
71
  racc (~> 1.4)
72
- nokogiri (1.16.5-x86_64-linux)
72
+ nokogiri (1.16.6-x86_64-linux)
73
73
  racc (~> 1.4)
74
- parallel (1.24.0)
75
- parser (3.3.2.0)
74
+ parallel (1.25.1)
75
+ parser (3.3.3.0)
76
76
  ast (~> 2.4.1)
77
77
  racc
78
78
  psych (5.1.2)
79
79
  stringio
80
80
  racc (1.8.0)
81
- rack (3.0.11)
81
+ rack (3.1.6)
82
82
  rack-session (2.0.0)
83
83
  rack (>= 3.0.0)
84
84
  rack-test (2.1.0)
@@ -93,9 +93,9 @@ GEM
93
93
  rails-html-sanitizer (1.6.0)
94
94
  loofah (~> 2.21)
95
95
  nokogiri (~> 1.14)
96
- railties (7.1.3.3)
97
- actionpack (= 7.1.3.3)
98
- activesupport (= 7.1.3.3)
96
+ railties (7.1.3.4)
97
+ actionpack (= 7.1.3.4)
98
+ activesupport (= 7.1.3.4)
99
99
  irb
100
100
  rackup (>= 1.0.0)
101
101
  rake (>= 12.2)
@@ -106,19 +106,19 @@ GEM
106
106
  rdoc (6.7.0)
107
107
  psych (>= 4.0.0)
108
108
  regexp_parser (2.9.2)
109
- reline (0.5.8)
109
+ reline (0.5.9)
110
110
  io-console (~> 0.5)
111
- rexml (3.2.8)
112
- strscan (>= 3.0.9)
111
+ rexml (3.3.1)
112
+ strscan
113
113
  rspec-core (3.13.0)
114
114
  rspec-support (~> 3.13.0)
115
- rspec-expectations (3.13.0)
115
+ rspec-expectations (3.13.1)
116
116
  diff-lcs (>= 1.2.0, < 2.0)
117
117
  rspec-support (~> 3.13.0)
118
118
  rspec-mocks (3.13.1)
119
119
  diff-lcs (>= 1.2.0, < 2.0)
120
120
  rspec-support (~> 3.13.0)
121
- rspec-rails (6.1.2)
121
+ rspec-rails (6.1.3)
122
122
  actionpack (>= 6.1)
123
123
  activesupport (>= 6.1)
124
124
  railties (>= 6.1)
@@ -140,17 +140,8 @@ GEM
140
140
  unicode-display_width (>= 2.4.0, < 3.0)
141
141
  rubocop-ast (1.31.3)
142
142
  parser (>= 3.3.1.0)
143
- rubocop-capybara (2.20.0)
144
- rubocop (~> 1.41)
145
- rubocop-factory_bot (2.25.1)
146
- rubocop (~> 1.41)
147
- rubocop-rspec (2.29.2)
148
- rubocop (~> 1.40)
149
- rubocop-capybara (~> 2.17)
150
- rubocop-factory_bot (~> 2.22)
151
- rubocop-rspec_rails (~> 2.28)
152
- rubocop-rspec_rails (2.28.3)
153
- rubocop (~> 1.40)
143
+ rubocop-rspec (3.0.2)
144
+ rubocop (~> 1.61)
154
145
  ruby-progressbar (1.13.0)
155
146
  simplecov (0.22.0)
156
147
  docile (~> 1.1)
@@ -161,7 +152,7 @@ GEM
161
152
  simplecov (~> 0.19)
162
153
  simplecov-html (0.12.3)
163
154
  simplecov_json_formatter (0.1.4)
164
- stringio (3.1.0)
155
+ stringio (3.1.1)
165
156
  strscan (3.1.0)
166
157
  thor (1.3.1)
167
158
  tzinfo (2.0.6)
@@ -169,7 +160,7 @@ GEM
169
160
  unicode-display_width (2.5.0)
170
161
  webrick (1.8.1)
171
162
  yard (0.9.36)
172
- zeitwerk (2.6.15)
163
+ zeitwerk (2.6.16)
173
164
 
174
165
  PLATFORMS
175
166
  aarch64-linux
@@ -182,11 +173,11 @@ PLATFORMS
182
173
 
183
174
  DEPENDENCIES
184
175
  always!
185
- minitest (= 5.23.1)
176
+ minitest (= 5.24.1)
186
177
  rake (= 13.2.1)
187
- rspec-rails (= 6.1.2)
178
+ rspec-rails (= 6.1.3)
188
179
  rubocop (= 1.64.1)
189
- rubocop-rspec (= 2.29.2)
180
+ rubocop-rspec (= 3.0.2)
190
181
  simplecov (= 0.22.0)
191
182
  simplecov-cobertura (= 2.1.0)
192
183
  yard (= 0.9.36)
data/README.md CHANGED
@@ -15,9 +15,9 @@ This simple Ruby gem helps you run a loop forever, in a background thread.
15
15
 
16
16
  ```ruby
17
17
  require 'always'
18
- # Prepare, with five threads and 30-seconds delay between loop cycles:
19
- a = Always.new(5, 30)
20
- # Start them all together spinning forever:
18
+ # Prepare, with five threads:
19
+ a = Always.new(5)
20
+ # Start them all together spinning forever with 30-seconds delay between cycles:
21
21
  a.start do
22
22
  puts "I'm alive"
23
23
  end
@@ -25,6 +25,18 @@ end
25
25
  a.stop
26
26
  ```
27
27
 
28
+ You may be interested to get the backtraces of the exceptions that
29
+ happened most recently:
30
+
31
+ ```ruby
32
+ # Keep the last 10 error backtraces in memory:
33
+ a = Always.new(5, max_backtraces: 10)
34
+ # Retrieve them:
35
+ p a.backtraces
36
+ ```
37
+
38
+ That's it.
39
+
28
40
  ## How to contribute
29
41
 
30
42
  Read
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.4'
29
+ s.version = '0.0.5'
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
@@ -33,29 +33,37 @@ require 'concurrent/atom'
33
33
  # puts 'Hello, world!
34
34
  # end
35
35
  #
36
- # Then, in order stop them all together:
36
+ # Then, in order to stop them all together:
37
37
  #
38
38
  # a.stop
39
39
  #
40
40
  # It's possible to get a quick summary of the thread pool, by calling +to_s+.
41
+ # The result will be a +"T/C/E"+ string, where +T+ is the total number of
42
+ # currently running threads, +C+ is the total number of all cycles
43
+ # so far, and +E+ is the total number of all errors seen so far.
41
44
  #
42
45
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
43
46
  # Copyright:: Copyright (c) 2024 Yegor Bugayenko
44
47
  # License:: MIT
45
48
  class Always
49
+ attr_reader :backtraces
50
+
46
51
  # The version of the framework.
47
- VERSION = '0.0.4'
52
+ VERSION = '0.0.5'
48
53
 
49
54
  # Constructor.
50
55
  # @param [Integer] total The number of threads to run
51
- def initialize(total)
56
+ # @param [Integer] max_backtraces How many backtraces to keep in memory?
57
+ def initialize(total, max_backtraces: 32)
52
58
  raise "The number of threads (#{total}) must be positive" unless total.positive?
53
59
 
54
60
  @total = total
55
61
  @on_error = nil
56
62
  @threads = []
63
+ @backtraces = []
57
64
  @cycles = Concurrent::Atom.new(0)
58
65
  @errors = Concurrent::Atom.new(0)
66
+ @max_backtraces = max_backtraces
59
67
  end
60
68
 
61
69
  # What to do when an exception occurs?
@@ -76,7 +84,7 @@ class Always
76
84
  self
77
85
  end
78
86
 
79
- # Start them all.
87
+ # Start them all and let them run forever (until the +stop+ method is called).
80
88
  # @param [Integer] pause The delay between cycles, in seconds
81
89
  def start(pause = 0, &)
82
90
  raise 'It is running now, call .stop() first' unless @threads.empty?
@@ -130,6 +138,8 @@ class Always
130
138
  yield
131
139
  rescue Exception => e
132
140
  @errors.swap { |c| c + 1 }
141
+ @backtraces << e
142
+ @backtraces.shift if @backtraces.size > @max_backtraces
133
143
  @on_error&.call(e)
134
144
  end
135
145
  # rubocop:enable Lint/RescueException
data/test/test_always.rb CHANGED
@@ -47,6 +47,19 @@ class TestAlways < Minitest::Test
47
47
  assert(failures.positive?)
48
48
  end
49
49
 
50
+ def test_read_backtraces
51
+ max = 5
52
+ a = Always.new(5, max_backtraces: max)
53
+ failures = 0
54
+ a.on_error { |_e| failures += 1 }.start do
55
+ raise 'intentionally'
56
+ end
57
+ sleep(0.1)
58
+ a.stop
59
+ assert(failures.positive?)
60
+ assert_equal(max, a.backtraces.size)
61
+ end
62
+
50
63
  def test_converts_to_string
51
64
  n = 6
52
65
  a = Always.new(6)
@@ -77,4 +90,17 @@ class TestAlways < Minitest::Test
77
90
  a.stop
78
91
  assert(done.positive?)
79
92
  end
93
+
94
+ def test_with_broken_syntax
95
+ a = Always.new(1)
96
+ failures = 0
97
+ a.on_error { |_e| failures += 1 }.start do
98
+ eval('broken$ruby$syntax')
99
+ end
100
+ sleep(0.1)
101
+ _, _, errors = a.to_s.split('/')
102
+ assert(!errors.to_i.zero?)
103
+ assert(!failures.zero?)
104
+ a.stop
105
+ end
80
106
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: always
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-31 00:00:00.000000000 Z
11
+ date: 2024-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby