process_bot 0.1.27 → 0.1.29

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: 016c72db98675857edb0e34b274af5cc835d0cd5496d4bb6fccb7ebdaf05c555
4
- data.tar.gz: 51a18efde6ff957df0dfe6f8e07e9df2f341a1519b3f17356de1ef7422f21e85
3
+ metadata.gz: 26b4a49cb5489140c90c0712ed2a9b686a43d531ab1290ee63fec7710371ca31
4
+ data.tar.gz: 857a0fc1d15a79dbb87a92f25ded46706953b0215e64f47d135eb96ba9cf90d3
5
5
  SHA512:
6
- metadata.gz: f2387a26b91b32675f6679af84f4e4096bde512f62f344a962a0312abea804395e6013b88f268c20094a04724f27c71680c421f63893c785f47586b472f68ff8
7
- data.tar.gz: '0491239c4e11851cfef5704cbbc9e79611c356595192f5187199fd3a7c898f7e61e5885a302ed84cdedb53692a4bf7e89369791fe69a169663273d95b5f4ebd8'
6
+ metadata.gz: 9d14944e3d8976d0077f20e83560558bd9af1d58247c849ef7cc03d4205c017925108fc2360cdd99059480f7aaf05e5fdaf464ea19fded430a540f168136963b
7
+ data.tar.gz: d22b2ec8c5c7483bad6bee7ab51060164f811b601f448e1f81bdd8b86e2c0b57eae39779e05347984c065a45449b59058586b490f3a3ebf421fc80f1a865998d
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- process_bot (0.1.27)
4
+ process_bot (0.1.29)
5
5
  knjrbfw (>= 0.0.116)
6
6
  pry
7
7
  rake
@@ -18,7 +18,7 @@ GEM
18
18
  http2 (0.0.36)
19
19
  string-cases (~> 0)
20
20
  io-console (0.8.2)
21
- json (2.18.0)
21
+ json (2.19.3)
22
22
  knjrbfw (0.0.116)
23
23
  datet
24
24
  http2
@@ -30,14 +30,14 @@ GEM
30
30
  lint_roller (1.1.0)
31
31
  method_source (1.1.0)
32
32
  parallel (1.27.0)
33
- parser (3.3.10.0)
33
+ parser (3.3.11.1)
34
34
  ast (~> 2.4.1)
35
35
  racc
36
36
  php4r (0.0.4)
37
37
  datet
38
38
  http2
39
39
  string-strtr
40
- prism (1.7.0)
40
+ prism (1.9.0)
41
41
  pry (0.16.0)
42
42
  coderay (~> 1.1)
43
43
  method_source (~> 1.0)
@@ -58,11 +58,11 @@ GEM
58
58
  rspec-expectations (3.13.5)
59
59
  diff-lcs (>= 1.2.0, < 2.0)
60
60
  rspec-support (~> 3.13.0)
61
- rspec-mocks (3.13.7)
61
+ rspec-mocks (3.13.8)
62
62
  diff-lcs (>= 1.2.0, < 2.0)
63
63
  rspec-support (~> 3.13.0)
64
64
  rspec-support (3.13.7)
65
- rubocop (1.82.1)
65
+ rubocop (1.86.0)
66
66
  json (~> 2.3)
67
67
  language_server-protocol (~> 3.17.0.2)
68
68
  lint_roller (~> 1.1.0)
@@ -70,10 +70,10 @@ GEM
70
70
  parser (>= 3.3.0.2)
71
71
  rainbow (>= 2.2.2, < 4.0)
72
72
  regexp_parser (>= 2.9.3, < 3.0)
73
- rubocop-ast (>= 1.48.0, < 2.0)
73
+ rubocop-ast (>= 1.49.0, < 2.0)
74
74
  ruby-progressbar (~> 1.7)
75
75
  unicode-display_width (>= 2.4.0, < 4.0)
76
- rubocop-ast (1.49.0)
76
+ rubocop-ast (1.49.1)
77
77
  parser (>= 3.3.7.2)
78
78
  prism (~> 1.7)
79
79
  rubocop-performance (1.26.1)
data/Rakefile CHANGED
@@ -7,6 +7,6 @@ require "rubocop/rake_task"
7
7
  RSpec::Core::RakeTask.new(:spec)
8
8
  RuboCop::RakeTask.new
9
9
 
10
- Dir[File.expand_path("../lib/tasks/**/*.rake", __FILE__)].each { |f| load f }
10
+ Dir[File.expand_path("lib/tasks/**/*.rake", __dir__)].each { |f| load f }
11
11
 
12
12
  task default: %i[spec rubocop]
@@ -3,6 +3,8 @@ require "knjrbfw"
3
3
  class ProcessBot::Process::Runner
4
4
  attr_reader :command, :exit_status, :handler_instance, :handler_name, :logger, :monitor, :options, :pid, :stop_time, :subprocess_pid
5
5
 
6
+ READ_CHUNK_SIZE = 4096
7
+
6
8
  def initialize(command:, handler_instance:, handler_name:, logger:, options:)
7
9
  @command = command
8
10
  @handler_instance = handler_instance
@@ -16,6 +18,17 @@ class ProcessBot::Process::Runner
16
18
  logger.log(output, type: type)
17
19
  end
18
20
 
21
+ def stream_output(io, type:)
22
+ buffer = +""
23
+
24
+ loop do
25
+ buffer << io.readpartial(READ_CHUNK_SIZE)
26
+ flush_complete_lines(type: type, buffer: buffer)
27
+ end
28
+ rescue EOFError, Errno::EIO
29
+ flush_remaining_output(type: type, buffer: buffer)
30
+ end
31
+
19
32
  def running?
20
33
  !stop_time
21
34
  end
@@ -31,13 +44,7 @@ class ProcessBot::Process::Runner
31
44
  logger.logs "Command running with PID #{pid}: #{command}"
32
45
 
33
46
  stdout_reader_thread = Thread.new do
34
- stdout.each_char do |chunk|
35
- monitor.synchronize do
36
- output(type: :stdout, output: chunk)
37
- end
38
- end
39
- rescue Errno::EIO
40
- # Process done
47
+ stream_output(stdout, type: :stdout)
41
48
  ensure
42
49
  status = Process::Status.wait(subprocess_pid, 0)
43
50
 
@@ -46,11 +53,7 @@ class ProcessBot::Process::Runner
46
53
  end
47
54
 
48
55
  stderr_reader_thread = Thread.new do
49
- stderr_reader.each_char do |chunk|
50
- monitor.synchronize do
51
- output(type: :stderr, output: chunk)
52
- end
53
- end
56
+ stream_output(stderr_reader, type: :stderr)
54
57
  end
55
58
 
56
59
  find_sidekiq_pid if handler_name == "sidekiq"
@@ -182,4 +185,37 @@ class ProcessBot::Process::Runner
182
185
  break
183
186
  end
184
187
  end
188
+
189
+ def flush_complete_lines(type:, buffer:)
190
+ loop do
191
+ separator_index = next_separator_index(buffer)
192
+ break unless separator_index
193
+
194
+ monitor.synchronize do
195
+ output(type: type, output: buffer.slice!(0, separator_index + 1))
196
+ end
197
+ end
198
+
199
+ return if buffer.bytesize < READ_CHUNK_SIZE
200
+
201
+ monitor.synchronize do
202
+ output(type: type, output: buffer.dup)
203
+ end
204
+
205
+ buffer.clear
206
+ end
207
+
208
+ def flush_remaining_output(type:, buffer:)
209
+ return if buffer.empty?
210
+
211
+ monitor.synchronize do
212
+ output(type: type, output: buffer.dup)
213
+ end
214
+
215
+ buffer.clear
216
+ end
217
+
218
+ def next_separator_index(buffer)
219
+ buffer.index(/[\r\n]/)
220
+ end
185
221
  end
@@ -8,7 +8,6 @@ class ProcessBot::Process # rubocop:disable Metrics/ClassLength
8
8
 
9
9
  def_delegator :handler_instance, :graceful
10
10
  def_delegator :handler_instance, :graceful_no_wait
11
- def_delegator :handler_instance, :stop
12
11
 
13
12
  autoload :Handlers, "#{__dir__}/process/handlers"
14
13
  autoload :Runner, "#{__dir__}/process/runner"
@@ -122,6 +121,11 @@ class ProcessBot::Process # rubocop:disable Metrics/ClassLength
122
121
  logger.logs "Stop process #{args}"
123
122
  @stopped = true
124
123
  handler_instance.stop
124
+
125
+ if runner_instances.empty?
126
+ logger.logs "No runner instances remaining, signaling main loop to exit"
127
+ runner_events << {type: :stopped, runner_instance: nil}
128
+ end
125
129
  end
126
130
 
127
131
  def run
@@ -1,3 +1,3 @@
1
1
  module ProcessBot
2
- VERSION = "0.1.27".freeze
2
+ VERSION = "0.1.29".freeze
3
3
  end
@@ -4,7 +4,7 @@ require "pathname"
4
4
  require "rubygems/version"
5
5
  require "shellwords"
6
6
 
7
- class ProcessBotRubygemsRelease # rubocop:disable Lint/ConstantDefinitionInBlock
7
+ class ProcessBotRubygemsRelease
8
8
  VERSION_FILE = Pathname.new(File.expand_path("../process_bot/version.rb", __dir__)) unless const_defined?(:VERSION_FILE)
9
9
 
10
10
  def call
@@ -60,16 +60,7 @@ private
60
60
  end
61
61
 
62
62
  def bumped_version
63
- case bump_type
64
- when "major"
65
- [version_segments[0] + 1, 0, 0].join(".")
66
- when "minor"
67
- [version_segments[0], version_segments[1] + 1, 0].join(".")
68
- when "patch"
69
- [version_segments[0], version_segments[1], version_segments[2] + 1].join(".")
70
- else
71
- raise "Unsupported BUMP=#{bump_type.inspect}. Use patch, minor, major, or VERSION=x.y.z."
72
- end
63
+ build_version(*bumped_version_segments)
73
64
  end
74
65
 
75
66
  def version_segments
@@ -84,6 +75,25 @@ private
84
75
  @current_version ||= VERSION_FILE.read[/VERSION = "([^"]+)"\.freeze/, 1] || raise("Could not find current version")
85
76
  end
86
77
 
78
+ def bumped_version_segments
79
+ segments = version_segments
80
+
81
+ case bump_type
82
+ when "major"
83
+ [segments[0] + 1, 0, 0]
84
+ when "minor"
85
+ [segments[0], segments[1] + 1, 0]
86
+ when "patch"
87
+ [segments[0], segments[1], segments[2] + 1]
88
+ else
89
+ raise "Unsupported BUMP=#{bump_type.inspect}. Use patch, minor, major, or VERSION=x.y.z."
90
+ end
91
+ end
92
+
93
+ def build_version(major, minor, patch)
94
+ [major, minor, patch].join(".")
95
+ end
96
+
87
97
  def bump_version!(next_version)
88
98
  raise "Next version must differ from current version" if next_version == current_version
89
99
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: process_bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.27
4
+ version: 0.1.29
5
5
  platform: ruby
6
6
  authors:
7
7
  - kaspernj
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-04-04 00:00:00.000000000 Z
11
+ date: 2026-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: knjrbfw