Skip to content
This repository has been archived by the owner on Sep 21, 2022. It is now read-only.

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
anderscarling committed May 29, 2012
0 parents commit f163f28
Show file tree
Hide file tree
Showing 9 changed files with 176 additions and 0 deletions.
17 changes: 17 additions & 0 deletions .gitignore
@@ -0,0 +1,17 @@
*.gem
*.rbc
.bundle
.config
.yardoc
Gemfile.lock
InstalledFiles
_yardoc
coverage
doc/
lib/bundler/man
pkg
rdoc
spec/reports
test/tmp
test/version_tmp
tmp
4 changes: 4 additions & 0 deletions Gemfile
@@ -0,0 +1,4 @@
source 'https://rubygems.org'

# Specify your gem's dependencies in unicorn-timeout.gemspec
gemspec
22 changes: 22 additions & 0 deletions LICENSE
@@ -0,0 +1,22 @@
Copyright (c) 2012 Anders Carling

MIT License

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
53 changes: 53 additions & 0 deletions README.md
@@ -0,0 +1,53 @@
# Unicorn::Timeout

Middleware for timing out current unicorn worker if request takes to long time.

If a request times out, a handler block will be called and the current worker
process will be killed (using SIGTERM).

## Compatibility

The gem is tested using Ruby 1.9.3p194.

## Installation

Add this line to your application's Gemfile:

gem 'unicorn-timeout'

And then execute:

$ bundle

Or install it yourself as:

$ gem install unicorn-timeout

## Setup/Usage (Rails 3)

In `config/application.rb`:

config.middleware.use Unicorn::Timeout

In `config/initializer/unicorn-timeout.rb` (optional):

# Timeout in seconds
Unicorn::Timeout.timeout = 15 # default

# Block that will run (within Thread.exclusive, on monitor thread) just before sending signal to process
Unicorn::Timeout.handler = lambda { |backtrace| STDERR.puts("Unicorn::Timeout is killing worker ##{Process.pid} with backtrace:\n#{backtrace.inspect}") } # default

# Signal that will be sent to current process if timeout is reached
Unicorn::Timeout.signal = "TERM" # default

## Contributing

1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Added some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request

## Credit

This work was inspired and influenced by [rack-timeout](https://github.com/kch/rack-timeout).
2 changes: 2 additions & 0 deletions Rakefile
@@ -0,0 +1,2 @@
#!/usr/bin/env rake
require "bundler/gem_tasks"
2 changes: 2 additions & 0 deletions lib/unicorn-timeout.rb
@@ -0,0 +1,2 @@
require "unicorn/timeout/version"
require "unicorn/timeout"
54 changes: 54 additions & 0 deletions lib/unicorn/timeout.rb
@@ -0,0 +1,54 @@
module Unicorn
class Timeout
@timeout = 15
@handler = lambda { |backtrace| STDERR.puts("Unicorn::Timeout is killing worker ##{Process.pid} with backtrace:\n#{backtrace.inspect}") }
@signal = "TERM"
class << self
attr_accessor :timeout
attr_accessor :handler
attr_accessor :signal
end

def initialize(app)
@app = app
end

def call(env)
t = setup_mon_thread

begin
@app.call(env)
ensure
kill_mon_thread(t)
end
end

private
def setup_mon_thread
main_thread = Thread.current

Thread.new do
sleep(self.class.timeout)
kill_main_thread(main_thread)
end
end

def kill_main_thread(t)
Thread.exclusive do
begin
self.class.handler.call(t.backtrace)
ensure
Process.kill(self.class.signal, Process.pid)
end
end
end

def kill_mon_thread(t)
Thread.exclusive do
t.kill
t.join
end
end

end
end
5 changes: 5 additions & 0 deletions lib/unicorn/timeout/version.rb
@@ -0,0 +1,5 @@
module Unicorn
class Timeout
VERSION = "1.0.0"
end
end
17 changes: 17 additions & 0 deletions unicorn-timeout.gemspec
@@ -0,0 +1,17 @@
# -*- encoding: utf-8 -*-
require File.expand_path('../lib/unicorn/timeout/version', __FILE__)

Gem::Specification.new do |gem|
gem.authors = ["Anders Carling"]
gem.email = ["anders.carling@d05.se"]
gem.description = %q{Middleware for timing out current unicorn worker if request takes to long time.}
gem.summary = %q{Middleware for timing out current unicorn worker if request takes to long time.}
gem.homepage = "http://www.github.com/FootballAddicts/unicorn-timeout"

gem.files = `git ls-files`.split($\)
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
gem.name = "unicorn-timeout"
gem.require_paths = ["lib"]
gem.version = Unicorn::Timeout::VERSION
end

0 comments on commit f163f28

Please sign in to comment.