process_bot 0.1.27 → 0.1.28
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 +4 -4
- data/AGENTS.md +1 -1
- data/CHANGELOG.md +1 -1
- data/Gemfile.lock +2 -2
- data/Rakefile +1 -1
- data/lib/process_bot/process/runner.rb +48 -12
- data/lib/process_bot/version.rb +1 -1
- data/lib/tasks/release.rake +10 -4
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e123dbde56775d5539bb91d48be68c1f83a09a2b001c6a61a1334aa3dba2b1ab
|
|
4
|
+
data.tar.gz: 34f9ff90352cad06e742ba69f7d4402d095678359caded93b20204f89b804a44
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8cbc29f75c5ffa3358f8614c11698fc4ac6548efa5a00a4d63a1004300707c80b395eb9229b877b06cc93c1d3b7e10987fa99d02f1942c67a133db277d9af49b
|
|
7
|
+
data.tar.gz: 8042fcbf747ba1162120b87e54d64bd1ac972615eaca4288865864ea76747e27d94b697b8de97d0a38ede453abbc9c30e5a54fdc3af32052f9ff466c82b9d311
|
data/AGENTS.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
- Made graceful shutdown waiting optional and defaulted Capistrano to not wait.
|
|
10
10
|
- Kept graceful handling synchronous and verified `bundle exec rspec`.
|
|
11
11
|
- Enabled ProcessBot logging by default for Capistrano hooks (configurable via `process_bot_log`).
|
|
12
|
-
- Always run RuboCop against changed or created Ruby files.
|
|
12
|
+
- Always run RuboCop against changed or created Ruby files before pushing or opening a PR.
|
|
13
13
|
- Added `graceful_no_wait` command and Capistrano task for non-blocking graceful shutdowns.
|
|
14
14
|
- Always add or update tests for new/changed functionality, and run them.
|
|
15
15
|
- Added coverage for graceful_no_wait and Capistrano wait defaults.
|
data/CHANGELOG.md
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
- Add optional Sidekiq restart overlap and a new ProcessBot restart command.
|
|
9
9
|
- Guard stop-related process scanning when subprocess PID/PGID is unavailable and fail stop loudly.
|
|
10
10
|
- Wait briefly for subprocess PID assignment during stop; raise if PID is still missing so stop cannot silently succeed.
|
|
11
|
-
|
|
12
11
|
- Require an active runner for custom stop commands to avoid constructing a fresh runner with no PID.
|
|
12
|
+
- Buffer subprocess output by line before broadcasting it to control clients so Capistrano does not receive one-character log chunks.
|
|
13
13
|
|
|
14
14
|
## [0.1.0] - 2022-04-03
|
|
15
15
|
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
process_bot (0.1.
|
|
4
|
+
process_bot (0.1.28)
|
|
5
5
|
knjrbfw (>= 0.0.116)
|
|
6
6
|
pry
|
|
7
7
|
rake
|
|
@@ -58,7 +58,7 @@ 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.
|
|
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)
|
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("
|
|
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
|
|
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
|
|
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
|
data/lib/process_bot/version.rb
CHANGED
data/lib/tasks/release.rake
CHANGED
|
@@ -4,7 +4,7 @@ require "pathname"
|
|
|
4
4
|
require "rubygems/version"
|
|
5
5
|
require "shellwords"
|
|
6
6
|
|
|
7
|
-
class ProcessBotRubygemsRelease
|
|
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,13 +60,15 @@ private
|
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
def bumped_version
|
|
63
|
+
major, minor, patch = version_segments
|
|
64
|
+
|
|
63
65
|
case bump_type
|
|
64
66
|
when "major"
|
|
65
|
-
|
|
67
|
+
format_version(major + 1, 0, 0)
|
|
66
68
|
when "minor"
|
|
67
|
-
|
|
69
|
+
format_version(major, minor + 1, 0)
|
|
68
70
|
when "patch"
|
|
69
|
-
|
|
71
|
+
format_version(major, minor, patch + 1)
|
|
70
72
|
else
|
|
71
73
|
raise "Unsupported BUMP=#{bump_type.inspect}. Use patch, minor, major, or VERSION=x.y.z."
|
|
72
74
|
end
|
|
@@ -84,6 +86,10 @@ private
|
|
|
84
86
|
@current_version ||= VERSION_FILE.read[/VERSION = "([^"]+)"\.freeze/, 1] || raise("Could not find current version")
|
|
85
87
|
end
|
|
86
88
|
|
|
89
|
+
def format_version(major, minor, patch)
|
|
90
|
+
[major, minor, patch].join(".")
|
|
91
|
+
end
|
|
92
|
+
|
|
87
93
|
def bump_version!(next_version)
|
|
88
94
|
raise "Next version must differ from current version" if next_version == current_version
|
|
89
95
|
|
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.
|
|
4
|
+
version: 0.1.28
|
|
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-
|
|
11
|
+
date: 2026-04-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: knjrbfw
|