rack-timeout 0.5.1 → 0.6.1

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: 642f765e106069393a85355bb1b205479b125e9e4fb639c4b8b7f8309b5563ea
4
- data.tar.gz: 0d8dc45b11b4561760d7163526b9926f8c566ed8c29ff83f7665cc890360da9e
3
+ metadata.gz: fafa5a90f1af90fdcc6ce081752ba684aac2652c1fd31867274ab9fc01a7c778
4
+ data.tar.gz: 6b3f1a800e031218a1e026737614b9d087d037c9ae8407ef788b3f2d404cb50a
5
5
  SHA512:
6
- metadata.gz: 33ee501f48e9ab8a7399fca2ec9c2ec1c3c26b10e6352b4371e4ca4b01706186457146556dbdcf38e82483e4348eb8815bd77dd15ea7e350e473e56c6f784249
7
- data.tar.gz: eaf9a7f04e9b2f1b3404d4fcf2a8f88d368cc0ed4e24b1c9df3cedd032ca41e63879c3064c02652e718fd0a6693756a2b303e832a4f1ffa03b595bfcc168c555
6
+ metadata.gz: 9390e4bb587d82e2ae0574397f9e02d61c5a13e162d980ad972d174f158d43a241949fdc77ae34d4206f01ec2dbd92d9c66d6bdb886ed4065dace963daf30b15
7
+ data.tar.gz: e4d838274207478d4ca0767bac9b702640aebdaada4ca2aa4f077fc79c23d4c34ab7744d2b3af44c58479cf5ad1a09e3c11e241add93eb6f5c906883c7dd4291
data/CHANGELOG.md ADDED
@@ -0,0 +1,120 @@
1
+ ## 0.6.1
2
+
3
+ - RACK_TIMEOUT_TERM_ON_TIMEOUT can be set to zero to disable (https://github.com/sharpstone/rack-timeout/pull/161)
4
+
5
+ ## 0.6.0
6
+
7
+ - Allow sending SIGTERM to workers on timeout (https://github.com/sharpstone/rack-timeout/pull/157)
8
+
9
+ 0.5.2
10
+ =====
11
+ - Rails 6 support (#147)
12
+
13
+ 0.5.1
14
+ =====
15
+ - Fixes setting ENV vars to false or 0 would not disable a timeout
16
+ (#133)
17
+
18
+ 0.5.0.1
19
+ =======
20
+ - Fix 0600 permissions in gem pushed to rubygems
21
+
22
+ 0.5.0
23
+ =====
24
+
25
+ Breaking Changes
26
+
27
+ - Remove Rollbar module (#124)
28
+ - Remove legacy class setters (#125)
29
+
30
+ Other
31
+
32
+ - Add support to configure via environment variables (#105)
33
+ - Adds support for ActionDispatch::RequestId generated request ids (#115)
34
+ - Changes uuid format to proper uuid (#115)
35
+
36
+ 0.4.2
37
+ =====
38
+ - Ruby 2.0 compatible
39
+
40
+ 0.4.1
41
+ =====
42
+ - Rails 5 support
43
+ - Remove deprecation warning on timeout setter for Rails apps
44
+
45
+ 0.4.0
46
+ =====
47
+ - Using monotonic time instead of Time.now where available (/ht concurrent-ruby)
48
+ - Settings are now passable to the middleware initializer instead of class-level
49
+ - Rollbar module may take a custom fingerprint block
50
+ - Rollbar module considered final
51
+ - Fixed an issue where some heartbeats would live on forever (#103, /ht @0x0badc0de)
52
+
53
+ 0.3.2
54
+ =====
55
+ - Fixes calling timeout with a value of 0 (issue #90)
56
+
57
+ 0.3.1
58
+ =====
59
+ - Rollbar module improvements
60
+
61
+ 0.3.0
62
+ =====
63
+ - use a single scheduler thread to manage timeouts, instead of one timeout thread per request
64
+ - instead of inserting middleware at position 0 for rails, insert before Rack::Runtime (which is right after Rack::Lock and the static file stuff)
65
+ - reshuffle error types: RequestExpiryError is again a RuntimeError, and timeouts raise a RequestTimeoutException, an Exception, and not descending from Rack::Timeout::Error (see README for more)
66
+ - don't insert middleware for rails in test environment
67
+ - add convenience module Rack::Timeout::Logger (see README for more)
68
+ - StageChangeLoggingObserver renamed to StateChangeLoggingObserver, works slightly differently too
69
+ - file layout reorganization (see 6e82c276 for details)
70
+ - CHANGELOG file is now in the gem (@dbackeus)
71
+ - add optional and experimental support for grouping errors by url under rollbar. see "rack/timeout/rollbar" for usage
72
+
73
+ 0.2.4
74
+ =====
75
+ - Previous fix was borked.
76
+
77
+ 0.2.3
78
+ =====
79
+ - Ignore Rack::NullLogger when picking a logger
80
+
81
+ 0.2.1
82
+ =====
83
+ - Fix raised error messages
84
+
85
+ 0.2.0
86
+ =====
87
+ - Added CHANGELOG
88
+ - Rack::Timeout::Error now inherits from Exception instead of StandardError, with the hope users won't rescue from it accidentally
89
+
90
+ 0.1.2
91
+ =====
92
+ - improve RequestTimeoutError error string so @watsonian is happy
93
+
94
+ 0.1.1
95
+ =====
96
+ - README updates
97
+ - fix that setting properties to false resulted in an error
98
+
99
+ 0.1.0
100
+ =====
101
+ - Rewrote README
102
+
103
+ 0.1.0beta4
104
+ ==========
105
+ - Renamed `timeout` setting to `service_timeout`; `timeout=` still works for backwards compatibility
106
+ – `MAX_REQUEST_AGE` is gone, the `wait_timeout` setting more or less replaces it
107
+ - Renamed `overtime` setting to `wait_overtime`
108
+ - overtime setting should actually work (It had never made it to beta3)
109
+ - In the request info struct, renamed `age` to `wait`, `duration` to `service`
110
+ - Rack::Timeout::StageChangeLogger is gone, replaced by Rack::Timeout::StageChangeLoggingObserver, which is an observer class that composites with a logger, instead of inheriting from Logger. Anything logging related will likely be incompatible with previous beta release.
111
+ - Log level can no longer be set with env vars, has to be set in the logger being used. (Which can now be custom / user-provided.)
112
+
113
+ 0.1.0beta1,2,3
114
+ ==============
115
+ - Dropped ruby 1.8.x support
116
+ - Dropped rails 2 support
117
+ - Added rails 4 support
118
+ - Added much logging
119
+ – Added support for dropping requests that waited too long in the queue without ever handling them
120
+ - Other things I can't remember, see git logs :P
data/README.md ADDED
@@ -0,0 +1,118 @@
1
+ Rack::Timeout
2
+ =============
3
+
4
+ Abort requests that are taking too long; an exception is raised.
5
+
6
+ A timeout of 15s is the default. It's recommended to set the timeout as
7
+ low as realistically viable for your application. You can modify this by
8
+ setting the `RACK_TIMEOUT_SERVICE_TIMEOUT` environment variable.
9
+
10
+ There's a handful of other settings, read on for details.
11
+
12
+ Rack::Timeout is not a solution to the problem of long-running requests,
13
+ it's a debug and remediation tool. App developers should track
14
+ rack-timeout's data and address recurring instances of particular
15
+ timeouts, for example by refactoring code so it runs faster or
16
+ offsetting lengthy work to happen asynchronously.
17
+
18
+ Upgrading
19
+ ---------
20
+
21
+ For fixing issues when upgrading, please see [UPGRADING](UPGRADING.md).
22
+
23
+ Basic Usage
24
+ -----------
25
+
26
+ The following covers currently supported versions of Rails, Rack, Ruby,
27
+ and Bundler. See the Compatibility section at the end for legacy
28
+ versions.
29
+
30
+ ### Rails apps
31
+
32
+ ```ruby
33
+ # Gemfile
34
+ gem "rack-timeout"
35
+ ```
36
+
37
+ This will load rack-timeout and set it up as a Rails middleware using
38
+ the default timeout of 15s. The middleware is not inserted for the test
39
+ environment. You can modify the timeout by setting a
40
+ `RACK_TIMEOUT_SERVICE_TIMEOUT` environment variable.
41
+
42
+ ### Rails apps, manually
43
+
44
+ You'll need to do this if you removed `Rack::Runtime` from the
45
+ middleware stack, or if you want to determine yourself where in the
46
+ stack `Rack::Timeout` gets inserted.
47
+
48
+ ```ruby
49
+ # Gemfile
50
+ gem "rack-timeout", require: "rack/timeout/base"
51
+ ```
52
+
53
+ ```ruby
54
+ # config/initializers/rack_timeout.rb
55
+
56
+ # insert middleware wherever you want in the stack, optionally pass
57
+ # initialization arguments, or use environment variables
58
+ Rails.application.config.middleware.insert_before Rack::Runtime, Rack::Timeout, service_timeout: 15
59
+ ```
60
+
61
+ ### Sinatra and other Rack apps
62
+
63
+ ```ruby
64
+ # config.ru
65
+ require "rack-timeout"
66
+
67
+ # Call as early as possible so rack-timeout runs before all other middleware.
68
+ # Setting service_timeout or `RACK_TIMEOUT_SERVICE_TIMEOUT` environment
69
+ # variable is recommended. If omitted, defaults to 15 seconds.
70
+ use Rack::Timeout, service_timeout: 15
71
+ ```
72
+
73
+ Configuring
74
+ -----------
75
+
76
+ Rack::Timeout takes the following settings, shown here with their
77
+ default values and associated environment variables.
78
+
79
+ ```
80
+ service_timeout: 15 # RACK_TIMEOUT_SERVICE_TIMEOUT
81
+ wait_timeout: 30 # RACK_TIMEOUT_WAIT_TIMEOUT
82
+ wait_overtime: 60 # RACK_TIMEOUT_WAIT_OVERTIME
83
+ service_past_wait: false # RACK_TIMEOUT_SERVICE_PAST_WAIT
84
+ term_on_timeout: false # RACK_TIMEOUT_TERM_ON_TIMEOUT
85
+ ```
86
+
87
+ These settings can be overriden during middleware initialization or
88
+ environment variables `RACK_TIMEOUT_*` mentioned above. Middleware
89
+ parameters take precedence:
90
+
91
+ ```ruby
92
+ use Rack::Timeout, service_timeout: 15, wait_timeout: 30
93
+ ```
94
+
95
+ For more on these settings, please see [doc/settings](doc/settings.md).
96
+
97
+ Further Documentation
98
+ ---------------------
99
+
100
+ Please see the [doc](doc) folder for further documentation on:
101
+
102
+ * [Risks and shortcomings of using Rack::Timeout](doc/risks.md)
103
+ * [Understanding the request lifecycle](doc/request-lifecycle.md)
104
+ * [Exceptions raised by Rack::Timeout](doc/exceptions.md)
105
+ * [Rollbar fingerprinting](doc/rollbar.md)
106
+ * [Observers](doc/observers.md)
107
+ * [Logging](doc/logging.md)
108
+
109
+ Compatibility
110
+ -------------
111
+
112
+ This version of Rack::Timeout is compatible with Ruby 2.1 and up, and,
113
+ for Rails apps, Rails 3.x and up.
114
+
115
+
116
+ ---
117
+ Copyright © 2010-2020 Caio Chassot, released under the MIT license
118
+ <http://github.com/sharpstone/rack-timeout>
data/UPGRADING.md ADDED
@@ -0,0 +1,19 @@
1
+ Upgrading
2
+ =========
3
+
4
+ From 0.4 or older
5
+ -----------------
6
+
7
+ - Removal of the class setters, such as `Rack::Timeout.timeout = 5`, may
8
+ lead to an error when upgrading. To fix this, remove these setters and
9
+ instead use either the [environment variables][config-env],
10
+ `RACK_TIMEOUT_*`, or [insert the middleware manually][config-insert]
11
+ and configure the middleware as desired when inserting.
12
+
13
+ [config-env]: README.md#configuring
14
+ [config-insert]: README.md#rails-apps-manually
15
+
16
+ - The Rollbar support was removed; a deprecation warning will be emitted
17
+ if you are using this module. The recommendation is to use Rollbar's
18
+ custom fingerprinting. A recommendation is provided in
19
+ [doc/rollbar.md](doc/rollbar.md).
data/doc/risks.md CHANGED
@@ -26,7 +26,6 @@ That said, it's something to be aware of, and may explain some eerie wonkiness s
26
26
  [broken-timeout]: http://headius.blogspot.de/2008/02/rubys-threadraise-threadkill-timeoutrb.html
27
27
  [handle-interrupt]: http://www.ruby-doc.org/core-2.1.3/Thread.html#method-c-handle_interrupt
28
28
 
29
-
30
29
  ### Time Out Early and Often
31
30
 
32
31
  Because of the aforementioned issues, it's recommended you set library-specific timeouts and leave Rack::Timeout as a last resort measure. Library timeouts will generally take care of IO issues and abort the operation safely. See [The Ultimate Guide to Ruby Timeouts][ruby-timeouts].
data/doc/settings.md CHANGED
@@ -47,3 +47,55 @@ This extra time is called *wait overtime* and can be set via `wait_overtime`. It
47
47
  Keep in mind that Heroku [recommends][uploads] uploading large files directly to S3, so as to prevent the dyno from being blocked for too long and hence unable to handle further incoming requests.
48
48
 
49
49
  [uploads]: https://devcenter.heroku.com/articles/s3#file-uploads
50
+
51
+ ### Term on Timeout
52
+
53
+ If your application timeouts fire frequently then [they can cause your application to enter a corrupt state](https://www.schneems.com/2017/02/21/the-oldest-bug-in-ruby-why-racktimeout-might-hose-your-server/). One option for resetting that bad state is to restart the entire process. If you are running in an environment with multiple processes (such as `puma -w 2`) then when a process is sent a `SIGTERM` it will exit. The webserver then knows how to restart the process. For more information on process restart behavior see:
54
+
55
+ - [Ruby Application Restart Behavior](https://devcenter.heroku.com/articles/what-happens-to-ruby-apps-when-they-are-restarted)
56
+ - [License to SIGKILL](https://www.sitepoint.com/license-to-sigkill/)
57
+
58
+ **Puma SIGTERM behavior** When a Puma worker receives a `SIGTERM` it will begin to shut down, but not exit right away. It stops accepting new requests and waits for any existing requests to finish before fully shutting down. This means that only the request that experiences a timeout will be interupted, all other in-flight requests will be allowed to run until they return or also are timed out.
59
+
60
+ After the worker process exists will Puma's parent process know to boot a replacement worker. While one process is restarting, another can still serve requests (if you have more than 1 worker process per server/dyno). Between when a process exits and when a new process boots, there will be a reduction in throughput. If all processes are restarting, then incoming requests will be blocked while new processes boot.
61
+
62
+ **How to enable** To enable this behavior you can set `term_on_timeout: 1` to an integer value. If you set it to one, then the first time the process encounters a timeout, it will receive a SIGTERM.
63
+
64
+ To enable on Heroku run:
65
+
66
+ ```
67
+ $ heroku config:set RACK_TIMEOUT_TERM_ON_TIMEOUT=1
68
+ ```
69
+
70
+ **Caution** If you use this setting inside of a webserver without enabling multi-process mode, then it will exit the entire server when it fires:
71
+
72
+ - ✅ `puma -w 2 -t 5` This is OKAY
73
+ - ❌ `puma -t 5` This is NOT OKAY
74
+
75
+ If you're using a `config/puma.rb` file then make sure you are calling `workers` configuration DSL. You should see multiple workers when the server boots:
76
+
77
+ ```
78
+ [3922] Puma starting in cluster mode...
79
+ [3922] * Version 4.3.0 (ruby 2.6.5-p114), codename: Mysterious Traveller
80
+ [3922] * Min threads: 0, max threads: 16
81
+ [3922] * Environment: development
82
+ [3922] * Process workers: 2
83
+ [3922] * Phased restart available
84
+ [3922] * Listening on tcp://0.0.0.0:9292
85
+ [3922] Use Ctrl-C to stop
86
+ [3922] - Worker 0 (pid: 3924) booted, phase: 0
87
+ [3922] - Worker 1 (pid: 3925) booted, phase: 0
88
+ ```
89
+
90
+ > ✅ Notice how it says it is booting in "cluster mode" and how it gives PIDs for two worker processes at the bottom.
91
+
92
+ **How to decide the term_on_timeout value** If you set to a higher value such as `5` then rack-timeout will wait until the process has experienced five timeouts before restarting the process. Setting this value to a higher number means the application restarts processes less frequently, so throughput will be less impacted. If you set it to too high of a number, then the underlying issue of the application being put into a bad state will not be effectively mitigated.
93
+
94
+
95
+ **How do I know when a process is being restarted by rack-timeout?** This exception error should be visible in the logs:
96
+
97
+ ```
98
+ Request ran for longer than 1000ms, sending SIGTERM to process 3925
99
+ ```
100
+
101
+ > Note: Since the worker waits for all in-flight requests to finish (with puma) you may see multiple SIGTERMs to the same PID before it exits, this means that multiple requests timed out.
@@ -30,6 +30,7 @@ module Rack
30
30
  :service, # time rack spent processing the request (updated ~ every second)
31
31
  :timeout, # the actual computed timeout to be used for this request
32
32
  :state, # the request's current state, see VALID_STATES below
33
+ :term,
33
34
  ) {
34
35
  def ms(k) # helper method used for formatting values in milliseconds
35
36
  "%.fms" % (self[k] * 1000) if self[k]
@@ -62,13 +63,20 @@ module Rack
62
63
  :service_timeout, # How long the application can take to complete handling the request once it's passed down to it.
63
64
  :wait_timeout, # How long the request is allowed to have waited before reaching rack. If exceeded, the request is 'expired', i.e. dropped entirely without being passed down to the application.
64
65
  :wait_overtime, # Additional time over @wait_timeout for requests with a body, like POST requests. These may take longer to be received by the server before being passed down to the application, but should not be expired.
65
- :service_past_wait # when false, reduces the request's computed timeout from the service_timeout value if the complete request lifetime (wait + service) would have been longer than wait_timeout (+ wait_overtime when applicable). When true, always uses the service_timeout value. we default to false under the assumption that the router would drop a request that's not responded within wait_timeout, thus being there no point in servicing beyond seconds_service_left (see code further down) up until service_timeout.
66
+ :service_past_wait, # when false, reduces the request's computed timeout from the service_timeout value if the complete request lifetime (wait + service) would have been longer than wait_timeout (+ wait_overtime when applicable). When true, always uses the service_timeout value. we default to false under the assumption that the router would drop a request that's not responded within wait_timeout, thus being there no point in servicing beyond seconds_service_left (see code further down) up until service_timeout.
67
+ :term_on_timeout
66
68
 
67
- def initialize(app, service_timeout:nil, wait_timeout:nil, wait_overtime:nil, service_past_wait:"not_specified")
69
+ def initialize(app, service_timeout:nil, wait_timeout:nil, wait_overtime:nil, service_past_wait:"not_specified", term_on_timeout: nil)
70
+ @term_on_timeout = read_timeout_property term_on_timeout, ENV.fetch("RACK_TIMEOUT_TERM_ON_TIMEOUT", 0).to_i
68
71
  @service_timeout = read_timeout_property service_timeout, ENV.fetch("RACK_TIMEOUT_SERVICE_TIMEOUT", 15).to_i
69
72
  @wait_timeout = read_timeout_property wait_timeout, ENV.fetch("RACK_TIMEOUT_WAIT_TIMEOUT", 30).to_i
70
73
  @wait_overtime = read_timeout_property wait_overtime, ENV.fetch("RACK_TIMEOUT_WAIT_OVERTIME", 60).to_i
71
74
  @service_past_wait = service_past_wait == "not_specified" ? ENV.fetch("RACK_TIMEOUT_SERVICE_PAST_WAIT", false).to_s != "false" : service_past_wait
75
+
76
+ Thread.main['RACK_TIMEOUT_COUNT'] ||= 0
77
+ if @term_on_timeout
78
+ raise "Current Runtime does not support processes" unless ::Process.respond_to?(:fork)
79
+ end
72
80
  @app = app
73
81
  end
74
82
 
@@ -90,7 +98,9 @@ module Rack
90
98
  seconds_waited = 0 if seconds_waited < 0 # make up for potential time drift between the routing server and the application server
91
99
  final_wait_timeout = wait_timeout + effective_overtime # how long the request will be allowed to have waited
92
100
  seconds_service_left = final_wait_timeout - seconds_waited # first calculation of service timeout (relevant if request doesn't get expired, may be overriden later)
93
- info.wait, info.timeout = seconds_waited, final_wait_timeout # updating the info properties; info.timeout will be the wait timeout at this point
101
+ info.wait = seconds_waited # updating the info properties; info.timeout will be the wait timeout at this point
102
+ info.timeout = final_wait_timeout
103
+
94
104
  if seconds_service_left <= 0 # expire requests that have waited for too long in the queue (as they are assumed to have been dropped by the web server / routing layer at this point)
95
105
  RT._set_state! env, :expired
96
106
  raise RequestExpiryError.new(env), "Request older than #{info.ms(:timeout)}."
@@ -103,7 +113,7 @@ module Rack
103
113
  # compute actual timeout to be used for this request; if service_past_wait is true, this is just service_timeout. If false (the default), and wait time was determined, we'll use the shortest value between seconds_service_left and service_timeout. See comment above at service_past_wait for justification.
104
114
  info.timeout = service_timeout # nice and simple, when service_past_wait is true, not so much otherwise:
105
115
  info.timeout = seconds_service_left if !service_past_wait && seconds_service_left && seconds_service_left > 0 && seconds_service_left < service_timeout
106
-
116
+ info.term = term_on_timeout
107
117
  RT._set_state! env, :ready # we're good to go, but have done nothing yet
108
118
 
109
119
  heartbeat_event = nil # init var so it's in scope for following proc
@@ -116,7 +126,22 @@ module Rack
116
126
 
117
127
  timeout = RT::Scheduler::Timeout.new do |app_thread| # creates a timeout instance responsible for timing out the request. the given block runs if timed out
118
128
  register_state_change.call :timed_out
119
- app_thread.raise(RequestTimeoutException.new(env), "Request #{"waited #{info.ms(:wait)}, then " if info.wait}ran for longer than #{info.ms(:timeout)}")
129
+
130
+ message = "Request "
131
+ message << "waited #{info.ms(:wait)}, then " if info.wait
132
+ message << "ran for longer than #{info.ms(:timeout)} "
133
+ if term_on_timeout
134
+ Thread.main['RACK_TIMEOUT_COUNT'] += 1
135
+
136
+ if Thread.main['RACK_TIMEOUT_COUNT'] >= @term_on_timeout
137
+ message << ", sending SIGTERM to process #{Process.pid}"
138
+ Process.kill("SIGTERM", Process.pid)
139
+ else
140
+ message << ", #{Thread.main['RACK_TIMEOUT_COUNT']}/#{term_on_timeout} timeouts allowed before SIGTERM for process #{Process.pid}"
141
+ end
142
+ end
143
+
144
+ app_thread.raise(RequestTimeoutException.new(env), message)
120
145
  end
121
146
 
122
147
  response = timeout.timeout(info.timeout) do # perform request with timeout
@@ -191,6 +216,5 @@ module Rack
191
216
  def self.notify_state_change_observers(env)
192
217
  @state_change_observers.values.each { |observer| observer.call(env) }
193
218
  end
194
-
195
219
  end
196
220
  end
@@ -35,5 +35,4 @@ module Rack::Timeout::Logger
35
35
  @level = new_level || ::Logger::INFO
36
36
  self.logger = ::Rack::Timeout::StateChangeLoggingObserver.mk_logger(device, level)
37
37
  end
38
-
39
38
  end
@@ -48,9 +48,9 @@ class Rack::Timeout::StateChangeLoggingObserver
48
48
  s << " wait=" << info.ms(:wait) if info.wait
49
49
  s << " timeout=" << info.ms(:timeout) if info.timeout
50
50
  s << " service=" << info.ms(:service) if info.service
51
+ s << " term_on_timeout=" << info.term.to_s if info.term
51
52
  s << " state=" << info.state.to_s if info.state
52
53
  s
53
54
  end
54
55
  end
55
-
56
56
  end
@@ -25,5 +25,4 @@ module Rack::Timeout::MonotonicTime
25
25
  when RUBY_PLATFORM == "java" ; alias fsecs fsecs_java
26
26
  else ; alias fsecs fsecs_ruby
27
27
  end
28
-
29
28
  end
@@ -151,5 +151,4 @@ class Rack::Timeout::Scheduler
151
151
  instance_methods(false).each do |m|
152
152
  define_singleton_method(m) { |*a, &b| singleton.send(m, *a, &b) }
153
153
  end
154
-
155
154
  end
@@ -25,5 +25,4 @@ class Rack::Timeout::Scheduler::Timeout
25
25
  def self.timeout(secs, &block)
26
26
  (@singleton ||= new).timeout(secs, &block)
27
27
  end
28
-
29
28
  end
data/lib/rack-timeout.rb CHANGED
@@ -1,2 +1,2 @@
1
1
  require_relative "rack/timeout/base"
2
- require_relative "rack/timeout/rails" if defined?(Rails) && [3,4,5].include?(Rails::VERSION::MAJOR)
2
+ require_relative "rack/timeout/rails" if defined?(Rails) && [3,4,5,6].include?(Rails::VERSION::MAJOR)
@@ -17,4 +17,11 @@ class EnvSettingsTest < RackTimeoutTest
17
17
  end
18
18
  end
19
19
 
20
+ def test_term
21
+ with_env(RACK_TIMEOUT_TERM_ON_TIMEOUT: 1) do
22
+ assert_raises(SignalException) do
23
+ get "/sleep"
24
+ end
25
+ end
26
+ end
20
27
  end
data/test/test_helper.rb CHANGED
@@ -42,5 +42,4 @@ class RackTimeoutTest < Test::Unit::TestCase
42
42
  def time_in_msec(t = Time.now)
43
43
  "#{t.tv_sec}#{t.tv_usec/1000}"
44
44
  end
45
-
46
45
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-timeout
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Caio Chassot
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-31 00:00:00.000000000 Z
11
+ date: 2022-06-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -59,9 +59,12 @@ executables: []
59
59
  extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
+ - CHANGELOG.md
62
63
  - Gemfile
63
64
  - MIT-LICENSE
65
+ - README.md
64
66
  - Rakefile
67
+ - UPGRADING.md
65
68
  - doc/exceptions.md
66
69
  - doc/logging.md
67
70
  - doc/observers.md
@@ -83,11 +86,15 @@ files:
83
86
  - test/basic_test.rb
84
87
  - test/env_settings_test.rb
85
88
  - test/test_helper.rb
86
- homepage: http://github.com/heroku/rack-timeout
89
+ homepage: https://github.com/sharpstone/rack-timeout
87
90
  licenses:
88
91
  - MIT
89
- metadata: {}
90
- post_install_message:
92
+ metadata:
93
+ bug_tracker_uri: https://github.com/sharpstone/rack-timeout/issues
94
+ changelog_uri: https://github.com/sharpstone/rack-timeout/blob/v0.6.1/CHANGELOG.md
95
+ documentation_uri: https://rubydoc.info/gems/rack-timeout/0.6.1/
96
+ source_code_uri: https://github.com/sharpstone/rack-timeout
97
+ post_install_message:
91
98
  rdoc_options: []
92
99
  require_paths:
93
100
  - lib
@@ -102,9 +109,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
102
109
  - !ruby/object:Gem::Version
103
110
  version: '0'
104
111
  requirements: []
105
- rubyforge_project:
106
- rubygems_version: 2.7.6
107
- signing_key:
112
+ rubygems_version: 3.3.7
113
+ signing_key:
108
114
  specification_version: 4
109
115
  summary: Abort requests that are taking too long
110
116
  test_files: