pitchfork 0.16.0 → 0.17.0
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/.github/workflows/ci.yml +8 -2
- data/CHANGELOG.md +10 -0
- data/Gemfile +1 -1
- data/README.md +12 -12
- data/Rakefile +14 -25
- data/docs/CONFIGURATION.md +36 -13
- data/docs/DESIGN.md +7 -7
- data/docs/FORK_SAFETY.md +3 -0
- data/docs/PHILOSOPHY.md +2 -2
- data/docs/REFORKING.md +12 -12
- data/docs/SIGNALS.md +7 -8
- data/docs/TUNING.md +3 -3
- data/examples/nginx.conf +1 -1
- data/examples/pitchfork.conf.rb +1 -1
- data/ext/pitchfork_http/c_util.h +2 -2
- data/ext/pitchfork_http/epollexclusive.h +2 -2
- data/lib/pitchfork/children.rb +1 -1
- data/lib/pitchfork/configurator.rb +13 -12
- data/lib/pitchfork/http_server.rb +64 -60
- data/lib/pitchfork/info.rb +3 -2
- data/lib/pitchfork/refork_condition.rb +1 -1
- data/lib/pitchfork/shared_memory.rb +36 -9
- data/lib/pitchfork/version.rb +1 -1
- data/lib/pitchfork/worker.rb +57 -34
- metadata +3 -3
data/lib/pitchfork/worker.rb
CHANGED
@@ -14,17 +14,17 @@ module Pitchfork
|
|
14
14
|
# :stopdoc:
|
15
15
|
EXIT_SIGNALS = [:QUIT, :TERM]
|
16
16
|
attr_accessor :nr, :pid, :generation
|
17
|
-
attr_reader :
|
17
|
+
attr_reader :monitor, :requests_count
|
18
18
|
|
19
19
|
def initialize(nr, pid: nil, generation: 0)
|
20
20
|
@nr = nr
|
21
21
|
@pid = pid
|
22
22
|
@generation = generation
|
23
23
|
@mold = false
|
24
|
-
@to_io = @
|
24
|
+
@to_io = @monitor = nil
|
25
25
|
@exiting = false
|
26
26
|
@requests_count = 0
|
27
|
-
|
27
|
+
init_state
|
28
28
|
end
|
29
29
|
|
30
30
|
def exiting?
|
@@ -32,7 +32,7 @@ module Pitchfork
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def pending?
|
35
|
-
@
|
35
|
+
@monitor.nil?
|
36
36
|
end
|
37
37
|
|
38
38
|
def outdated?
|
@@ -46,31 +46,31 @@ module Pitchfork
|
|
46
46
|
|
47
47
|
case message
|
48
48
|
when Message::MoldSpawned
|
49
|
-
@
|
49
|
+
@state_drop = SharedMemory.mold_promotion_state
|
50
50
|
when Message::MoldReady
|
51
|
-
@
|
51
|
+
@state_drop = SharedMemory.mold_state
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
def
|
55
|
+
def register_to_monitor(control_socket)
|
56
56
|
create_socketpair!
|
57
|
-
message = Message::WorkerSpawned.new(@nr, @pid, generation, @
|
57
|
+
message = Message::WorkerSpawned.new(@nr, @pid, generation, @monitor)
|
58
58
|
control_socket.sendmsg(message)
|
59
|
-
@
|
59
|
+
@monitor.close
|
60
60
|
end
|
61
61
|
|
62
62
|
def start_promotion(control_socket)
|
63
63
|
create_socketpair!
|
64
|
-
message = Message::MoldSpawned.new(@nr, @pid, generation, @
|
64
|
+
message = Message::MoldSpawned.new(@nr, @pid, generation, @monitor)
|
65
65
|
control_socket.sendmsg(message)
|
66
|
-
@
|
66
|
+
@monitor.close
|
67
67
|
end
|
68
68
|
|
69
69
|
def finish_promotion(control_socket)
|
70
70
|
message = Message::MoldReady.new(@nr, @pid, generation)
|
71
71
|
control_socket.sendmsg(message)
|
72
72
|
SharedMemory.current_generation = @generation
|
73
|
-
@
|
73
|
+
@state_drop = SharedMemory.mold_state
|
74
74
|
end
|
75
75
|
|
76
76
|
def promote(generation)
|
@@ -93,7 +93,7 @@ module Pitchfork
|
|
93
93
|
def promoted!(timeout)
|
94
94
|
@mold = true
|
95
95
|
@nr = nil
|
96
|
-
@
|
96
|
+
@state_drop = SharedMemory.mold_promotion_state
|
97
97
|
update_deadline(timeout) if timeout
|
98
98
|
self
|
99
99
|
end
|
@@ -110,8 +110,8 @@ module Pitchfork
|
|
110
110
|
@to_io.to_io
|
111
111
|
end
|
112
112
|
|
113
|
-
def
|
114
|
-
@
|
113
|
+
def monitor=(socket)
|
114
|
+
@monitor = MessageSocket.new(socket)
|
115
115
|
end
|
116
116
|
|
117
117
|
# call a signal handler immediately without triggering EINTR
|
@@ -126,7 +126,7 @@ module Pitchfork
|
|
126
126
|
trap(sig, old_cb)
|
127
127
|
end
|
128
128
|
|
129
|
-
#
|
129
|
+
# monitor sends fake signals to children
|
130
130
|
def soft_kill(sig) # :nodoc:
|
131
131
|
signum = Signal.list[sig.to_s] or raise ArgumentError, "BUG: bad signal: #{sig.inspect}"
|
132
132
|
|
@@ -149,7 +149,7 @@ module Pitchfork
|
|
149
149
|
case buf = @to_io.recvmsg_nonblock(exception: false)
|
150
150
|
when :wait_readable # keep waiting
|
151
151
|
return false
|
152
|
-
when nil # EOF
|
152
|
+
when nil # EOF monitor died, but we are at a safe place to exit
|
153
153
|
fake_sig(:QUIT)
|
154
154
|
return false
|
155
155
|
when Message::SoftKill
|
@@ -171,18 +171,29 @@ module Pitchfork
|
|
171
171
|
super || (!@nr.nil? && @nr == other)
|
172
172
|
end
|
173
173
|
|
174
|
+
def ready?
|
175
|
+
@state_drop.ready?
|
176
|
+
end
|
177
|
+
|
178
|
+
def ready=(bool)
|
179
|
+
@state_drop.ready = bool
|
180
|
+
end
|
181
|
+
|
174
182
|
def update_deadline(timeout)
|
175
183
|
self.deadline = Pitchfork.time_now(true) + timeout
|
176
184
|
end
|
177
185
|
|
178
186
|
# called in the worker process
|
179
187
|
def deadline=(value) # :nodoc:
|
180
|
-
|
188
|
+
# If we are (re)setting to zero mark worker as not ready.
|
189
|
+
self.ready = false if value == 0
|
190
|
+
|
191
|
+
@state_drop.deadline = value
|
181
192
|
end
|
182
193
|
|
183
|
-
# called in the
|
194
|
+
# called in the monitor process
|
184
195
|
def deadline # :nodoc:
|
185
|
-
@
|
196
|
+
@state_drop.deadline
|
186
197
|
end
|
187
198
|
|
188
199
|
def reset
|
@@ -193,26 +204,34 @@ module Pitchfork
|
|
193
204
|
@requests_count += by
|
194
205
|
end
|
195
206
|
|
196
|
-
# called in both the
|
207
|
+
# called in both the monitor (reaping worker) and worker (SIGQUIT handler)
|
197
208
|
def close # :nodoc:
|
198
209
|
self.deadline = 0
|
199
|
-
@
|
210
|
+
@monitor.close if @monitor
|
200
211
|
@to_io.close if @to_io
|
201
212
|
end
|
202
213
|
|
203
214
|
def create_socketpair!
|
204
|
-
@to_io, @
|
215
|
+
@to_io, @monitor = Info.keep_ios(Pitchfork.socketpair)
|
205
216
|
end
|
206
217
|
|
207
218
|
def after_fork_in_child
|
208
|
-
@
|
219
|
+
@monitor&.close
|
220
|
+
end
|
221
|
+
|
222
|
+
def to_log
|
223
|
+
if mold?
|
224
|
+
pid ? "mold gen=#{generation} pid=#{pid}" : "mold gen=#{generation}"
|
225
|
+
else
|
226
|
+
pid ? "worker=#{nr} gen=#{generation} pid=#{pid}" : "worker=#{nr} gen=#{generation}"
|
227
|
+
end
|
209
228
|
end
|
210
229
|
|
211
230
|
private
|
212
231
|
|
213
|
-
def
|
232
|
+
def init_state
|
214
233
|
if nr
|
215
|
-
@
|
234
|
+
@state_drop = SharedMemory.worker_state(@nr)
|
216
235
|
self.deadline = 0
|
217
236
|
else
|
218
237
|
promoted!(nil)
|
@@ -222,14 +241,14 @@ module Pitchfork
|
|
222
241
|
def pipe=(socket)
|
223
242
|
raise ArgumentError, "pipe can't be nil" unless socket
|
224
243
|
Info.keep_io(socket)
|
225
|
-
@
|
244
|
+
@monitor = MessageSocket.new(socket)
|
226
245
|
end
|
227
246
|
|
228
247
|
def send_message_nonblock(message)
|
229
248
|
success = false
|
230
|
-
return false unless @
|
249
|
+
return false unless @monitor
|
231
250
|
begin
|
232
|
-
case @
|
251
|
+
case @monitor.sendmsg_nonblock(message, exception: false)
|
233
252
|
when :wait_writable
|
234
253
|
else
|
235
254
|
success = true
|
@@ -250,17 +269,21 @@ module Pitchfork
|
|
250
269
|
true
|
251
270
|
end
|
252
271
|
|
253
|
-
def
|
272
|
+
def register_to_monitor(control_socket)
|
254
273
|
create_socketpair!
|
255
|
-
message = Message::ServiceSpawned.new(@pid, generation, @
|
274
|
+
message = Message::ServiceSpawned.new(@pid, generation, @monitor)
|
256
275
|
control_socket.sendmsg(message)
|
257
|
-
@
|
276
|
+
@monitor.close
|
277
|
+
end
|
278
|
+
|
279
|
+
def to_log
|
280
|
+
pid ? "service gen=#{generation} pid=#{pid}" : "service gen=#{generation}"
|
258
281
|
end
|
259
282
|
|
260
283
|
private
|
261
284
|
|
262
|
-
def
|
263
|
-
@
|
285
|
+
def init_state
|
286
|
+
@state_drop = SharedMemory.service_state
|
264
287
|
self.deadline = 0
|
265
288
|
end
|
266
289
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pitchfork
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.17.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean Boussier
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -141,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
141
141
|
- !ruby/object:Gem::Version
|
142
142
|
version: '0'
|
143
143
|
requirements: []
|
144
|
-
rubygems_version: 3.5.
|
144
|
+
rubygems_version: 3.5.9
|
145
145
|
signing_key:
|
146
146
|
specification_version: 4
|
147
147
|
summary: Rack HTTP server for fast clients and Unix
|