blue_green_process 0.1.3 → 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 +4 -4
- data/CHANGELOG.md +3 -0
- data/Gemfile.lock +1 -1
- data/README.md +24 -3
- data/lib/blue_green_process/master_process.rb +44 -2
- data/lib/blue_green_process/version.rb +1 -1
- data/lib/blue_green_process/worker_process.rb +8 -2
- data/lib/blue_green_process.rb +22 -1
- 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: c8905db7b63e35a80a3fa1272553fa4f84002e06747501b5749110a6edfed79e
|
4
|
+
data.tar.gz: 467fbb4d348d6fae9cfc70a013f88a560cc69a97690451d0b53908585d312e20
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f042564e95f91038d87faaae43d891d798204784a27f0b2fb1a038df195717c58755c7a65531216d97f4477296dee1775119ba1c01560c7fb067a336c1b613aa
|
7
|
+
data.tar.gz: 28d937c6280847b821ef49f4c247649549a13bf4a5c0f62d444cb6d5c391d88c491ac2d2fcca38a56947e4eb66b5583200885b4cc4e4f40c63cd61c2a8ac5bc1
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -2,6 +2,29 @@
|
|
2
2
|
|
3
3
|
A library that solves GC bottlenecks with multi-process.
|
4
4
|
|
5
|
+
```mermaid
|
6
|
+
sequenceDiagram
|
7
|
+
autonumber
|
8
|
+
loop
|
9
|
+
Master->>+Blue: be active
|
10
|
+
Blue->>-Master: response
|
11
|
+
Master->>+Blue: work
|
12
|
+
Blue->>-Master: response
|
13
|
+
Master->>+Blue: be inactive
|
14
|
+
Blue->>-Master: response
|
15
|
+
Blue-->>Blue: GC.start
|
16
|
+
Master->>+Green: be active
|
17
|
+
Green->>-Master: response
|
18
|
+
Master->>+Green: work
|
19
|
+
Green->>-Master: response
|
20
|
+
Master->>+Green: be inactive
|
21
|
+
Green->>-Master: response
|
22
|
+
Green->>Green: GC.start
|
23
|
+
end
|
24
|
+
|
25
|
+
```
|
26
|
+
|
27
|
+
|
5
28
|
## Installation
|
6
29
|
|
7
30
|
Install the gem and add to the application's Gemfile by executing:
|
@@ -31,6 +54,7 @@ end
|
|
31
54
|
sleep(1)
|
32
55
|
|
33
56
|
process.shutdown
|
57
|
+
# or BlueGreenProcess.terminate_workers_immediately
|
34
58
|
Process.waitall
|
35
59
|
```
|
36
60
|
|
@@ -148,6 +172,3 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
148
172
|
|
149
173
|
## TODO
|
150
174
|
* shutdownしないでプロセスを停止したときにSIGINTを受け取りたい
|
151
|
-
* runしている間にsignalをもらったらすぐにdieを送りたい
|
152
|
-
* inactiveからactiveへの切り替えになる時間を測定したい
|
153
|
-
* GCが長引いてactiveプロセスが処理開始に時間がかかるので
|
@@ -24,10 +24,18 @@ module BlueGreenProcess
|
|
24
24
|
@max_work = max_work
|
25
25
|
end
|
26
26
|
|
27
|
+
# @return [Array<Integer>]
|
28
|
+
# 削除予定
|
27
29
|
def pids
|
28
30
|
@processes.map(&:pid)
|
29
31
|
end
|
30
32
|
|
33
|
+
# @return [Array<Integer>]
|
34
|
+
def worker_pids
|
35
|
+
@processes.map(&:pid)
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [BlueGreenProcess::WorkerProcess]
|
31
39
|
def fork_process(label:, worker_instance:)
|
32
40
|
child_read, parent_write = IO.pipe
|
33
41
|
parent_read, child_write = IO.pipe
|
@@ -39,10 +47,12 @@ module BlueGreenProcess
|
|
39
47
|
parent_write.close
|
40
48
|
parent_read.close
|
41
49
|
process_status = :inactive
|
50
|
+
handle_signal(pipes: [child_read, child_write])
|
42
51
|
|
43
52
|
loop do
|
44
|
-
data = child_read.gets
|
45
|
-
|
53
|
+
next unless (data = child_read.gets)
|
54
|
+
|
55
|
+
json = JSON.parse(data.strip)
|
46
56
|
command = json["c"]
|
47
57
|
case command
|
48
58
|
when BlueGreenProcess::PROCESS_COMMAND_DIE, nil, ""
|
@@ -76,6 +86,8 @@ module BlueGreenProcess
|
|
76
86
|
puts "unknown. from #{label}(#{$PROCESS_ID})"
|
77
87
|
exit 1
|
78
88
|
end
|
89
|
+
rescue IOError # NOTE: シグナル経由でpipeが破棄された時にこれが発生する
|
90
|
+
exit 127
|
79
91
|
end
|
80
92
|
|
81
93
|
exit 0
|
@@ -87,6 +99,7 @@ module BlueGreenProcess
|
|
87
99
|
BlueGreenProcess::WorkerProcess.new(pid, label, parent_read, parent_write)
|
88
100
|
end
|
89
101
|
|
102
|
+
# @return [void]
|
90
103
|
def work
|
91
104
|
active_process do |process|
|
92
105
|
@max_work.times do
|
@@ -99,6 +112,7 @@ module BlueGreenProcess
|
|
99
112
|
raise eval(e.error_class), e.message
|
100
113
|
end
|
101
114
|
|
115
|
+
# @return [void]
|
102
116
|
def shutdown
|
103
117
|
@processes.each(&:shutdown)
|
104
118
|
Process.waitall
|
@@ -106,6 +120,7 @@ module BlueGreenProcess
|
|
106
120
|
|
107
121
|
private
|
108
122
|
|
123
|
+
# @return [void]
|
109
124
|
def active_process
|
110
125
|
active_process = nil
|
111
126
|
@stage[!@stage_state].be_inactive
|
@@ -126,5 +141,32 @@ module BlueGreenProcess
|
|
126
141
|
|
127
142
|
true
|
128
143
|
end
|
144
|
+
|
145
|
+
# @return [void]
|
146
|
+
# シグナルを受け取ってpipeをcloseする
|
147
|
+
def handle_signal(pipes:)
|
148
|
+
Thread.new do
|
149
|
+
self_read, self_write = IO.pipe
|
150
|
+
%w[INT TERM].each do |sig|
|
151
|
+
trap sig do
|
152
|
+
self_write.puts(sig)
|
153
|
+
end
|
154
|
+
rescue ArgumentError
|
155
|
+
warn("Signal #{sig} not supported")
|
156
|
+
end
|
157
|
+
|
158
|
+
begin
|
159
|
+
while (readable_io = IO.select([self_read]))
|
160
|
+
signal = readable_io.first[0].gets.strip
|
161
|
+
case signal
|
162
|
+
when "INT", "TERM"
|
163
|
+
raise Interrupt
|
164
|
+
end
|
165
|
+
end
|
166
|
+
rescue Interrupt
|
167
|
+
pipes.each(&:close)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
129
171
|
end
|
130
172
|
end
|
@@ -47,7 +47,9 @@ module BlueGreenProcess
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def wait_response
|
50
|
-
|
50
|
+
return unless (text = read)
|
51
|
+
|
52
|
+
response = JSON.parse(text.strip)
|
51
53
|
BlueGreenProcess::SharedVariable.instance.restore(response["data"])
|
52
54
|
case response["c"]
|
53
55
|
when BlueGreenProcess::RESPONSE_OK
|
@@ -60,11 +62,15 @@ module BlueGreenProcess
|
|
60
62
|
end
|
61
63
|
|
62
64
|
def read
|
63
|
-
rpipe.gets
|
65
|
+
rpipe.gets
|
66
|
+
rescue IOError
|
67
|
+
# NOTE: シグナル経由でpipeが破棄された時にこれが発生する
|
64
68
|
end
|
65
69
|
|
66
70
|
def write(token, args = {})
|
67
71
|
wpipe.puts({ c: token }.merge!(args).to_json)
|
72
|
+
rescue Errno::EPIPE
|
73
|
+
# NOTE: シグナル経由でpipeが破棄された時にこれが発生する
|
68
74
|
end
|
69
75
|
|
70
76
|
def enforce_to_be_active
|
data/lib/blue_green_process.rb
CHANGED
@@ -13,6 +13,8 @@ require "json"
|
|
13
13
|
require "singleton"
|
14
14
|
|
15
15
|
module BlueGreenProcess
|
16
|
+
PID_PATH = "/tmp/pbm_blue_green_process_pids"
|
17
|
+
|
16
18
|
PROCESS_STATUS_ACTIVE = :active
|
17
19
|
PROCESS_STATUS_INACTIVE = :inactive
|
18
20
|
|
@@ -25,7 +27,9 @@ module BlueGreenProcess
|
|
25
27
|
RESPONSE_ERROR = "ERR"
|
26
28
|
|
27
29
|
def self.new(worker_instance:, max_work:)
|
28
|
-
BlueGreenProcess::MasterProcess.new(worker_instance: worker_instance, max_work: max_work)
|
30
|
+
master_process = BlueGreenProcess::MasterProcess.new(worker_instance: worker_instance, max_work: max_work)
|
31
|
+
File.write(PID_PATH, master_process.worker_pids.join(","))
|
32
|
+
master_process
|
29
33
|
end
|
30
34
|
|
31
35
|
def self.configure
|
@@ -50,4 +54,21 @@ module BlueGreenProcess
|
|
50
54
|
@config = Config.new
|
51
55
|
@performance = Performance.new
|
52
56
|
end
|
57
|
+
|
58
|
+
# @return [void]
|
59
|
+
def self.terminate_workers_immediately
|
60
|
+
worker_pids = nil
|
61
|
+
begin
|
62
|
+
worker_pids = File.read(PID_PATH).split(",").map(&:to_i)
|
63
|
+
rescue Errno::ENOENT
|
64
|
+
warn("#{PID_PATH}にファイルがありませんでした")
|
65
|
+
return
|
66
|
+
end
|
67
|
+
|
68
|
+
worker_pids.each do |worker_pid|
|
69
|
+
Process.kill "TERM", worker_pid
|
70
|
+
rescue Errno::ESRCH => e
|
71
|
+
warn("BlueGreenProcess workerプロセス(#{worker_pid})の終了に失敗しました。", e.message)
|
72
|
+
end
|
73
|
+
end
|
53
74
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blue_green_process
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jiikko
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A library that solves GC bottlenecks with multi-process.
|
14
14
|
email:
|