unicorn-soft-timeout 0.0.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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