pitchfork 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f37584c7333941059ab10086a74d1102b1969c2fefb7a759fc13f9e4f837891e
4
- data.tar.gz: bc69759f0a53d98d81648ee60b833e6c49fd3f88d53f7ac319e9acff845c7cf1
3
+ metadata.gz: ccd444fbdc89d5a253819e7be03e5d097c5aaf8b061980e15d4ec5326d2c54b5
4
+ data.tar.gz: f300bd3135e8d8d9e15f14dfe2780c75521ececeb72b8245fef0380e2ba338f5
5
5
  SHA512:
6
- metadata.gz: 69d796bf414bb4bf7b7867e61229fa12764ca12dd1aaf2b36a615c2b806a64aa665b4c1483147e6d39a4d49df340ad31406f0db294da52e9a8a5740b186233a9
7
- data.tar.gz: 51dc5852d5bc26fbba0f1824beb76977653ae089d589e33a1d7defca89b9b2235f466c5fc59419f56d0944b6c5ee819e1f966e9c32eac3d79029d951a6071c38
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.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.7)
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 two slow, but it is not a
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.
@@ -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 of worker processes to a number of seconds.
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
- This timeout mecanism shouldn't be routinely relying on, and should
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, it is
191
- highly recommended to set a stricter one based on your application
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`