pitchfork 0.4.0 → 0.5.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.
Potentially problematic release.
This version of pitchfork might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/Gemfile.lock +2 -2
- data/docs/Application_Timeouts.md +1 -1
- data/docs/CONFIGURATION.md +77 -11
- data/ext/pitchfork_http/pitchfork_http.c +166 -166
- data/lib/pitchfork/chunked.rb +1 -1
- data/lib/pitchfork/configurator.rb +17 -6
- data/lib/pitchfork/http_server.rb +104 -25
- data/lib/pitchfork/soft_timeout.rb +113 -0
- data/lib/pitchfork/version.rb +1 -1
- data/lib/pitchfork/worker.rb +12 -8
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ccd444fbdc89d5a253819e7be03e5d097c5aaf8b061980e15d4ec5326d2c54b5
|
4
|
+
data.tar.gz: f300bd3135e8d8d9e15f14dfe2780c75521ececeb72b8245fef0380e2ba338f5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b054a33d46f4b60c14e44fbac330bc4318a1b52259e89f2e8a1c16a58d8467f02eef981dbe018906a0c7a027c98db75a8efd483619d7ea5e2ece234b30b3846f
|
7
|
+
data.tar.gz: b12a622275fe638d49be5d9457d11309421119f9628044dec9898231f83425cab6aa6434b9f42372c5f8954b261f7e979e300a41fa75c39172fb8e1832cb0805
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# Unreleased
|
2
2
|
|
3
|
+
- Added a soft timeout in addition to the historical Unicorn hard timeout.
|
4
|
+
On soft timeout, the `after_worker_timeout` callback is invoked.
|
5
|
+
- Implement `after_request_complete` callback.
|
6
|
+
|
7
|
+
# 0.4.1
|
8
|
+
|
9
|
+
- Avoid a Rack 3 deprecation warning.
|
10
|
+
- Fix handling on non-ASCII cookies.
|
11
|
+
- Log unknown process being reaped at INFO level.
|
12
|
+
|
3
13
|
# 0.4.0
|
4
14
|
|
5
15
|
- Preserve the current thread when reforking.
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
pitchfork (0.
|
4
|
+
pitchfork (0.5.0)
|
5
5
|
rack (>= 2.0)
|
6
6
|
raindrops (~> 0.7)
|
7
7
|
|
@@ -12,7 +12,7 @@ GEM
|
|
12
12
|
nio4r (2.5.8)
|
13
13
|
puma (6.1.1)
|
14
14
|
nio4r (~> 2.0)
|
15
|
-
rack (3.0.
|
15
|
+
rack (3.0.8)
|
16
16
|
raindrops (0.20.1)
|
17
17
|
rake (13.0.6)
|
18
18
|
rake-compiler (1.2.1)
|
@@ -70,5 +70,5 @@ handle network/server failures.
|
|
70
70
|
The `timeout` mechanism in pitchfork is an extreme solution that should
|
71
71
|
be avoided whenever possible.
|
72
72
|
It will help preserve the platform if your application or a dependency
|
73
|
-
has a bug that cause it to either get stuck or
|
73
|
+
has a bug that cause it to either get stuck or be too slow, but it is not a
|
74
74
|
solution to such bugs, merely a mitigation.
|
data/docs/CONFIGURATION.md
CHANGED
@@ -173,33 +173,55 @@ The following options may be specified (but are generally not needed):
|
|
173
173
|
### `timeout`
|
174
174
|
|
175
175
|
```ruby
|
176
|
-
timeout 10
|
176
|
+
timeout 10, cleanup: 3
|
177
177
|
```
|
178
178
|
|
179
|
-
Sets the timeout
|
180
|
-
Workers handling the request/app.call/response cycle taking longer than
|
181
|
-
this time period will be forcibly killed (via `SIGKILL`).
|
179
|
+
Sets the timeout for worker processes to a number of seconds.
|
182
180
|
|
183
|
-
|
181
|
+
Note that Pitchfork has two layers of timeout.
|
182
|
+
|
183
|
+
A first "soft" timeout will invoke the `after_worker_timeout` from
|
184
|
+
within the worker (but from a background thread) and then call `exit`
|
185
|
+
to terminate the worker cleanly.
|
186
|
+
|
187
|
+
The second "hard" timeout, is the sum of `timeout` and `cleanup`.
|
188
|
+
Workers taking longer than this time period to be ready to handle a new
|
189
|
+
request will be forcibly killed (via `SIGKILL`).
|
190
|
+
|
191
|
+
Neither of these timeout mecanisms should be routinely relied on, and should
|
184
192
|
instead be considered as a last line of defense in case you application
|
185
193
|
is impacted by bugs causing unexpectedly slow response time, or fully stuck
|
186
194
|
processes.
|
187
195
|
|
196
|
+
If some of the application endpoints require an unreasonably large timeout,
|
197
|
+
rather than to increase the global application timeout, it is possible to
|
198
|
+
adjust it on a per request basis via the rack request environment:
|
199
|
+
|
200
|
+
```ruby
|
201
|
+
class MyMiddleware
|
202
|
+
def call(env)
|
203
|
+
if slow_endpoint?(env)
|
204
|
+
# Give 10 more seconds
|
205
|
+
env["pitchfork.timeout"]&.extend_deadline(10)
|
206
|
+
end
|
207
|
+
@app.call(env)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
```
|
211
|
+
|
188
212
|
Make sure to read the guide on [application timeouts](Application_Timeouts.md).
|
189
213
|
|
190
|
-
This configuration defaults to a (too) generous 20 seconds
|
191
|
-
|
192
|
-
profile.
|
214
|
+
This configuration defaults to a (too) generous 20 seconds for the soft timeout
|
215
|
+
and an extra 2 seconds for the hard timeout. It is highly recommended to set a
|
216
|
+
stricter one based on your application profile.
|
193
217
|
|
194
|
-
This timeout is enforced by the master process itself and not subject
|
195
|
-
to the scheduling limitations by the worker process.
|
196
218
|
Due the low-complexity, low-overhead implementation, timeouts of less
|
197
219
|
than 3.0 seconds can be considered inaccurate and unsafe.
|
198
220
|
|
199
221
|
For running Pitchfork behind nginx, it is recommended to set
|
200
222
|
"fail_timeout=0" for in your nginx configuration like this
|
201
223
|
to have nginx always retry backends that may have had workers
|
202
|
-
SIGKILL-ed due to timeouts.
|
224
|
+
exit or be SIGKILL-ed due to timeouts.
|
203
225
|
|
204
226
|
```
|
205
227
|
upstream pitchfork_backend {
|
@@ -284,6 +306,36 @@ after_worker_ready do |server, worker|
|
|
284
306
|
end
|
285
307
|
```
|
286
308
|
|
309
|
+
### `after_worker_timeout`
|
310
|
+
|
311
|
+
Called by the worker process when the request timeout is elapsed:
|
312
|
+
|
313
|
+
```ruby
|
314
|
+
after_worker_timeout do |server, worker, timeout_info|
|
315
|
+
timeout_info.copy_thread_variables!
|
316
|
+
timeout_info.thread.kill
|
317
|
+
server.logger.error("Request timed out: #{timeout_info.rack_env.inspect}")
|
318
|
+
$stderr.puts timeout_info.thread.backtrace
|
319
|
+
end
|
320
|
+
```
|
321
|
+
|
322
|
+
Note that this callback is invoked from a different thread. You can access the
|
323
|
+
main thread via `timeout_info.thread`, as well as the rack environment via `timeout_info.rack_env`.
|
324
|
+
|
325
|
+
If you need to invoke cleanup code that rely on thread local state, you can copy
|
326
|
+
that state with `timeout_info.copy_thread_variables!`, but it's best avoided as the
|
327
|
+
thread local state could contain thread unsafe objects.
|
328
|
+
|
329
|
+
Also note that at this stage, the thread is still alive, if your callback does
|
330
|
+
substantial work, you may want to kill the thread.
|
331
|
+
|
332
|
+
After the callback is executed the worker will exit with status `0`.
|
333
|
+
|
334
|
+
It is recommended not to do slow operations in this callback, but if you
|
335
|
+
really have to, make sure to configure the `cleanup` timeout so that the
|
336
|
+
callback has time to complete before the "hard" timeout triggers.
|
337
|
+
By default the cleanup timeout is 2 seconds.
|
338
|
+
|
287
339
|
### `after_worker_exit`
|
288
340
|
|
289
341
|
Called in the master process after a worker exits.
|
@@ -297,6 +349,20 @@ after_worker_exit do |server, worker, status|
|
|
297
349
|
end
|
298
350
|
```
|
299
351
|
|
352
|
+
### `after_request_complete`
|
353
|
+
|
354
|
+
Called in the worker processes after a request has completed.
|
355
|
+
|
356
|
+
Can be used for out of band work, or to exit unhealthy workers.
|
357
|
+
|
358
|
+
```ruby
|
359
|
+
after_request_complete do |server, worker|
|
360
|
+
if something_wrong?
|
361
|
+
exit
|
362
|
+
end
|
363
|
+
end
|
364
|
+
```
|
365
|
+
|
300
366
|
## Reforking
|
301
367
|
|
302
368
|
### `refork_after`
|