unicorn-soft-timeout 0.0.1 → 0.2.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1e8e7534c2f58736c14c45d873c8b789f758946f
4
+ data.tar.gz: 65be8d82059bca947dbfd2129fe077b5c33903ad
5
+ SHA512:
6
+ metadata.gz: 446843280c827b22e27f8a71c4f885f145c5d8afa4180009a74d8720471315270d861095681fcafc2738be416b68d9b9ee06057f601e7fea54591167c2518df6
7
+ data.tar.gz: 3f87ef723bb1c9664352596ef13adfabaddca50821b7dd19ff07d202526387a8d28595918ac2033118486a7b2d4e50571ddefe8644aad89a1300cb774eae11e2
data/.gitignore CHANGED
@@ -1,6 +1,7 @@
1
1
  *.swp
2
2
  *.gem
3
3
  *.rbc
4
+ *.log
4
5
  .bundle
5
6
  .config
6
7
  .yardoc
@@ -0,0 +1,18 @@
1
+ language: ruby
2
+ cache: bundler
3
+ before_install:
4
+ - gem install bundler
5
+ rvm:
6
+ - 2.3
7
+ - 2.4
8
+ - ruby-head
9
+ - jruby-23mode
10
+ - jruby-head
11
+ - rubinius-3
12
+ matrix:
13
+ allow_failures:
14
+ - rvm: ruby-head
15
+ - rvm: jruby-head
16
+ - rvm: jruby-23mode
17
+ - rvm: rubinius-3
18
+ fast_finish: true
data/README.md CHANGED
@@ -1,11 +1,15 @@
1
- # Unicorn::SoftTimeout
1
+ # unicorn-soft-timeout
2
2
 
3
- This gem adds support for soft timeout in Unicorn. By default
4
- requests which are taking longer than configured **timeout** are
3
+ This gem adds support for **soft timeout** in [Unicorn](http://unicorn.bogomips.org/)
4
+ configurations, by default requests which are taking longer than configured `timeout` are
5
5
  [SIGKILL-ed](http://unicorn.bogomips.org/Unicorn/Configurator.html#method-i-timeout).
6
- In some cases we need to intercept those requests to display a
7
- custom content instead of the error page.
8
6
 
7
+ In some cases we need to intercept requests which will reach `timeout` to display a
8
+ custom content instead of the error page. This extension will raise `Timeout::Error`
9
+ when reaching the soft timeout and will restart the worker sending a `SIGQUIT`
10
+ signal to it.
11
+
12
+ - [![Build Status](https://travis-ci.org/vitalie/unicorn-soft-timeout.svg?branch=master)](https://travis-ci.org/vitalie/unicorn-soft-timeout)
9
13
 
10
14
  ## Installation
11
15
 
@@ -30,10 +34,13 @@ Edit your config.ru file and load the Unicorn::SoftTimeout middleware:
30
34
 
31
35
  # Specify your soft timeout (default 12 seconds), it should
32
36
  # be a lower value than **timeout** specified in your unicorn config.
33
- # This extension will raise Timeout::Error when reaching
34
- # the **soft timeout**.
35
37
  use Unicorn::SoftTimeout, 10
36
38
 
39
+ ## Credits
40
+
41
+ * [Kazuki Ohta](https://github.com/kzk)
42
+ * [Pierre Baillet](https://github.com/octplane)
43
+
37
44
  ## Contributing
38
45
 
39
46
  1. Fork it
data/Rakefile CHANGED
@@ -1 +1,17 @@
1
+ # encoding: UTF-8
1
2
  require "bundler/gem_tasks"
3
+ require "rake/testtask"
4
+ require "rdoc/task"
5
+
6
+ desc "Default: run tests."
7
+ task default: :test
8
+
9
+
10
+ desc "Run unit tests."
11
+ Rake::TestTask.new do |t|
12
+ t.libs << "test"
13
+ t.libs << "lib"
14
+ t.test_files = Dir[ "test/*_test.rb" ]
15
+ t.verbose = true
16
+ end
17
+
@@ -1,4 +1,4 @@
1
- require "unicorn/soft_timeout/version"
1
+ require 'unicorn/soft_timeout/version'
2
2
 
3
3
  module Unicorn
4
4
  module SoftTimeout
@@ -18,7 +18,7 @@ module Unicorn
18
18
  sleep(@_soft_timeout)
19
19
  logger.warn "#{self}: worker (pid: #{worker_pid}) exceeds soft timeout (limit: #{@_soft_timeout})"
20
20
  Process.kill :QUIT, worker_pid # graceful shutdown
21
- current_thread.raise Timeout::Error.new("Soft timeout exceeded")
21
+ current_thread.raise Timeout::Error.new('Soft timeout exceeded')
22
22
  end
23
23
 
24
24
  super(client) # Unicorn::HttpServer#process_client
@@ -26,4 +26,3 @@ module Unicorn
26
26
  end
27
27
  end
28
28
  end
29
-
@@ -1,5 +1,5 @@
1
1
  module Unicorn
2
2
  module SoftTimeout
3
- VERSION = "0.0.1"
3
+ VERSION = '0.2.0'
4
4
  end
5
5
  end
@@ -0,0 +1,65 @@
1
+ require 'unicorn'
2
+ require 'unicorn/soft_timeout'
3
+ require 'minitest/autorun'
4
+ require 'minitest/unit'
5
+ require 'net/http'
6
+
7
+ STDIN.sync = STDOUT.sync = STDERR.sync = true
8
+
9
+ DEFAULT_TRIES = 100
10
+ DEFAULT_RES = 0.2
11
+
12
+ def redirect_test_io
13
+ orig_err = STDERR.dup
14
+ orig_out = STDOUT.dup
15
+ STDERR.reopen("test_stderr.#{$$}.log", "a")
16
+ STDOUT.reopen("test_stdout.#{$$}.log", "a")
17
+ STDERR.sync = STDOUT.sync = true
18
+
19
+ at_exit do
20
+ File.unlink("test_stderr.#{$$}.log") rescue nil
21
+ File.unlink("test_stdout.#{$$}.log") rescue nil
22
+ end
23
+
24
+ begin
25
+ yield
26
+ ensure
27
+ STDERR.reopen(orig_err)
28
+ STDOUT.reopen(orig_out)
29
+ end
30
+ end
31
+
32
+ def wait_workers_ready(path, nr_workers)
33
+ tries = DEFAULT_TRIES
34
+ lines = []
35
+ while (tries -= 1) > 0
36
+ begin
37
+ lines = File.readlines(path).grep(/worker=\d+ ready/)
38
+ lines.size == nr_workers and return
39
+ rescue Errno::ENOENT
40
+ end
41
+ sleep DEFAULT_RES
42
+ end
43
+ raise "#{nr_workers} workers never became ready:" \
44
+ "\n\t#{lines.join("\n\t")}\n"
45
+ end
46
+
47
+ def hit(uris)
48
+ results = []
49
+ uris.each do |u|
50
+ res = nil
51
+
52
+ if u.kind_of? String
53
+ u = 'http://127.0.0.1:8080/' if u == 'http://0.0.0.0:8080/'
54
+ res = Net::HTTP.get(URI.parse(u))
55
+ else
56
+ url = URI.parse(u[0])
57
+ res = Net::HTTP.new(url.host, url.port).start {|h| h.request(u[1]) }
58
+ end
59
+
60
+ assert res != nil, "Didn't get a response: #{u}"
61
+ results << res
62
+ end
63
+
64
+ return results
65
+ end
@@ -0,0 +1,42 @@
1
+ require 'test_helper'
2
+
3
+ include Unicorn
4
+
5
+ class TestHandler
6
+ def call(env)
7
+ while env['rack.input'].read(4096)
8
+ end
9
+ sleep 5
10
+ [200, { 'Content-Type' => 'text/plain' }, ['hello!\n']]
11
+ rescue Timeout::Error
12
+ [200, { 'Content-Type' => 'text/plain' }, ['timeout!\n']]
13
+ rescue Unicorn::ClientShutdown, Unicorn::HttpParserError => e
14
+ $stderr.syswrite("#{e.class}: #{e.message} #{e.backtrace.empty?}\n")
15
+ raise e
16
+ end
17
+ end
18
+
19
+ class UnicornSoftTimeoutTest < Minitest::Test
20
+ def setup
21
+ @port = 5000
22
+ @tester = TestHandler.new
23
+ redirect_test_io do
24
+ @server = Unicorn::HttpServer.new(@tester, listeners: ["127.0.0.1:#{@port}"])
25
+ @tester = Unicorn::SoftTimeout.new(@tester, 3)
26
+ @server.start
27
+ end
28
+ end
29
+
30
+ def teardown
31
+ redirect_test_io do
32
+ wait_workers_ready("test_stderr.#$$.log", 1)
33
+ File.truncate("test_stderr.#$$.log", 0)
34
+ @server.stop(false)
35
+ end
36
+ end
37
+
38
+ def test_simple_server
39
+ results = hit(["http://localhost:#{@port}/test"])
40
+ assert_equal 'timeout!\n', results[0], "Handler didn't really run"
41
+ end
42
+ end
@@ -18,8 +18,9 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_dependency "unicorn", "~> 4"
21
+ spec.add_dependency "unicorn", "~> 5"
22
22
 
23
- spec.add_development_dependency "bundler", "~> 1.3"
23
+ spec.add_development_dependency "minitest"
24
24
  spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "bump"
25
26
  end
metadata CHANGED
@@ -1,62 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unicorn-soft-timeout
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
5
- prerelease:
4
+ version: 0.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Vitalie Cherpec
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-06-12 00:00:00.000000000 Z
11
+ date: 2017-07-11 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: unicorn
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ~>
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
- version: '4'
19
+ version: '5'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ~>
24
+ - - "~>"
28
25
  - !ruby/object:Gem::Version
29
- version: '4'
26
+ version: '5'
30
27
  - !ruby/object:Gem::Dependency
31
- name: bundler
28
+ name: minitest
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ~>
31
+ - - ">="
36
32
  - !ruby/object:Gem::Version
37
- version: '1.3'
33
+ version: '0'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ~>
38
+ - - ">="
44
39
  - !ruby/object:Gem::Version
45
- version: '1.3'
40
+ version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rake
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bump
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
52
60
  - !ruby/object:Gem::Version
53
61
  version: '0'
54
62
  type: :development
55
63
  prerelease: false
56
64
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
65
  requirements:
59
- - - ! '>='
66
+ - - ">="
60
67
  - !ruby/object:Gem::Version
61
68
  version: '0'
62
69
  description: Graceful handling of requests which are reaching the timeout limit to
@@ -67,37 +74,41 @@ executables: []
67
74
  extensions: []
68
75
  extra_rdoc_files: []
69
76
  files:
70
- - .gitignore
77
+ - ".gitignore"
78
+ - ".travis.yml"
71
79
  - Gemfile
72
80
  - LICENSE.txt
73
81
  - README.md
74
82
  - Rakefile
75
83
  - lib/unicorn/soft_timeout.rb
76
84
  - lib/unicorn/soft_timeout/version.rb
85
+ - test/test_helper.rb
86
+ - test/unicorn_soft_timeout_test.rb
77
87
  - unicorn-soft-timeout.gemspec
78
88
  homepage: https://github.com/vitalie/unicorn-soft-timeout
79
89
  licenses:
80
90
  - MIT
91
+ metadata: {}
81
92
  post_install_message:
82
93
  rdoc_options: []
83
94
  require_paths:
84
95
  - lib
85
96
  required_ruby_version: !ruby/object:Gem::Requirement
86
- none: false
87
97
  requirements:
88
- - - ! '>='
98
+ - - ">="
89
99
  - !ruby/object:Gem::Version
90
100
  version: '0'
91
101
  required_rubygems_version: !ruby/object:Gem::Requirement
92
- none: false
93
102
  requirements:
94
- - - ! '>='
103
+ - - ">="
95
104
  - !ruby/object:Gem::Version
96
105
  version: '0'
97
106
  requirements: []
98
107
  rubyforge_project:
99
- rubygems_version: 1.8.24
108
+ rubygems_version: 2.4.5.1
100
109
  signing_key:
101
- specification_version: 3
110
+ specification_version: 4
102
111
  summary: Unicorn soft timeout
103
- test_files: []
112
+ test_files:
113
+ - test/test_helper.rb
114
+ - test/unicorn_soft_timeout_test.rb