upstart-unicorn-launcher 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d109d9f24ae93e72009230eb434e0a9abcafa2b6
4
+ data.tar.gz: 981df7c77180b3896c5bca99157843939b888fff
5
+ SHA512:
6
+ metadata.gz: df7459fba6ab6f0f2c03a54ed0356c47a1116f7d3f21299abbe5b39655f6a48e171c3eafeb1d10b3cd768e7cc32fccb57eefbba5cc9dbd4c615318ff45aaae31
7
+ data.tar.gz: 62a444ff416ca8334264e026c333d3454081e01381be722e4ad11b9bebc9a757687f8d1df501563f9f313dbf17983780bc11d58651199a795d452a14cf6b64e6
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in upstart-unicorn-launcher.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Tom Ward
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1 @@
1
+ A simple unicorn launcher for use with upstart, in the same manner as https://github.com/alphagov/unicornherder
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'upstart_unicorn_launcher'
4
+ require 'optparse'
5
+
6
+ options = {}
7
+
8
+ command_index = ARGV.index("--")
9
+ command = ARGV[command_index + 1..-1].join(" ")
10
+
11
+ OptionParser.new do |opts|
12
+ opts.on("-p", "--pidfile PIDFILE", "Path to the main unicorn PIDFILE") do |pidfile|
13
+ options[:pidfile] = pidfile
14
+ end
15
+
16
+ opts.on("-s", "--startup-time STARTUP", "Time to wait for server to start") do |time|
17
+ options[:startup] = time.to_i
18
+ end
19
+ end.parse!(ARGV[0...command_index])
20
+
21
+ launcher = UpstartUnicornLauncher.new command, options
22
+ launcher.start
@@ -0,0 +1 @@
1
+ require "upstart_unicorn_launcher"
@@ -0,0 +1,3 @@
1
+ class UpstartUnicornLauncher
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,104 @@
1
+ require "upstart_unicorn_launcher/version"
2
+
3
+ class UpstartUnicornLauncher
4
+ attr_accessor :command, :pidfile, :startup_period, :tick_period, :restarting
5
+
6
+ def initialize(command, options = {})
7
+ self.command = command
8
+ self.pidfile = File.expand_path(options[:pidfile] || 'unicorn.pid')
9
+ self.startup_period = options[:startup] || 60
10
+ self.tick_period = options[:tick] || 1
11
+ end
12
+
13
+ def start
14
+ debug "Starting server"
15
+ restart_server_on :HUP
16
+ quit_server_on :QUIT, :INT, :TERM
17
+ forward_to_server :USR1, :USR2, :WINCH, :TTIN, :TTOU
18
+ start_server
19
+ wait_until_server_quits
20
+ end
21
+
22
+ private
23
+
24
+ def start_server
25
+ abort "The unicorn pidfile '#{pidfile}' already exists. Is the server running already?" if File.exist?(pidfile)
26
+ spawned_pid = Process.spawn command
27
+ sleep 0.5
28
+ unless File.exist?(pidfile)
29
+ Process.kill "QUIT", spawned_pid
30
+ abort "Unable to find server running with pidfile #{pidfile}. Exiting"
31
+ end
32
+ end
33
+
34
+ def restart_server_on(*signals)
35
+ signals.each do |signal|
36
+ trap(signal.to_s) { restart_server }
37
+ end
38
+ end
39
+
40
+ def quit_server_on(*signals)
41
+ signals.each do |signal|
42
+ trap(signal.to_s) do
43
+ Process.kill signal.to_s, pid
44
+ exit
45
+ end
46
+ end
47
+ end
48
+
49
+ def forward_to_server(*signals)
50
+ signals.each do |signal|
51
+ trap(signal.to_s) do
52
+ debug "Forwarding #{signal} to #{pid}"
53
+ Process.kill signal.to_s, pid
54
+ end
55
+ end
56
+ end
57
+
58
+ def wait_until_server_quits
59
+ while running?
60
+ sleep tick_period
61
+ end
62
+ end
63
+
64
+ def restart_server
65
+ reexecute_running_binary
66
+ wait_for_server_to_start
67
+ quit_old_master
68
+ end
69
+
70
+ def reexecute_running_binary
71
+ Process.kill "USR2", pid
72
+ end
73
+
74
+ def wait_for_server_to_start
75
+ sleep startup_period
76
+ end
77
+
78
+ def quit_old_master
79
+ if old_pid
80
+ Process.kill "QUIT", old_pid
81
+ end
82
+ end
83
+
84
+ def pid
85
+ File.exist?(pidfile) && File.read(pidfile).to_i
86
+ end
87
+
88
+ def old_pid
89
+ old_pidfile = pidfile + ".oldbin"
90
+ File.exist?(old_pidfile) && File.read(old_pidfile).to_i
91
+ end
92
+
93
+ def running?
94
+ pid && Process.getpgid(pid)
95
+ rescue Errno::ESRCH
96
+ false
97
+ end
98
+
99
+ private
100
+
101
+ def debug(message)
102
+ puts message
103
+ end
104
+ end
@@ -0,0 +1,24 @@
1
+ module ProjectSupport
2
+ def perform_request
3
+ response = Curl::Easy.perform('http://localhost:7516')
4
+ end
5
+
6
+ def start_launcher
7
+ @launcher_pid = Process.spawn "upstart-unicorn-launcher -s 1 -p spec/templates/test/unicorn.pid -- unicorn -p 7516 -c spec/templates/test/unicorn.rb spec/templates/test/config.ru"
8
+ sleep 1
9
+ puts "Launched upstart-unicorn-launcher with PID #{@launcher_pid}"
10
+ end
11
+
12
+ def send_to_launcher(signal)
13
+ Process.kill signal, @launcher_pid
14
+ end
15
+
16
+ def kill_launcher
17
+ puts "Killing #{@launcher_pid}"
18
+ Process.kill "QUIT", @launcher_pid
19
+ end
20
+ end
21
+
22
+ RSpec.configure do |config|
23
+ config.include ProjectSupport
24
+ end
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gem 'unicorn'
@@ -0,0 +1,4 @@
1
+ # A very simple server that always responds with the time it was started. This
2
+ # is used in tests to check whether the server has started or restarted
3
+ time = Time.now.to_f
4
+ run lambda { |env| [200, {"Content-Type" => "text/plain"}, ["#{time}"]] }
@@ -0,0 +1 @@
1
+ pid "/Users/tomw/Projects/tools/upstart-unicorn-launcher/spec/templates/test/unicorn.pid"
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+ require 'curl'
3
+
4
+ describe 'Upstart integration' do
5
+ after :each do
6
+ kill_launcher
7
+ end
8
+
9
+ it 'starts server' do
10
+ start_launcher
11
+ expect {perform_request}.to_not raise_error
12
+ end
13
+
14
+ it 'stops server when sent QUIT' do
15
+ start_launcher
16
+ send_to_launcher 'QUIT'
17
+ sleep 1
18
+ expect {perform_request}.to raise_error
19
+ end
20
+
21
+ it 'stops server when sent INT' do
22
+ start_launcher
23
+ send_to_launcher 'INT'
24
+ sleep 1
25
+ expect {perform_request}.to raise_error
26
+ end
27
+
28
+ it 'stops server when sent TERM' do
29
+ start_launcher
30
+ send_to_launcher 'INT'
31
+ sleep 1
32
+ expect {perform_request}.to raise_error
33
+ end
34
+
35
+ it 'restarts server when sent HUP' do
36
+ start_launcher
37
+ original_response = perform_request.body_str
38
+ send_to_launcher 'HUP'
39
+ sleep 1
40
+ expect(perform_request.body_str).to_not eql(original_response)
41
+ end
42
+
43
+ it 'continues to serve requests during restart' do
44
+ start_launcher
45
+ start = Time.now
46
+ send_to_launcher 'HUP'
47
+ responses = []
48
+ while Time.now < (start + 2)
49
+ expect {responses << perform_request.body_str}.to_not raise_error
50
+ end
51
+ expect(responses.uniq.size).to eql(2)
52
+ end
53
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/upstart_unicorn_launcher/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Tom Ward"]
6
+ gem.email = ["tom@popdog.net"]
7
+ gem.description = %q{Launch unicorn with upstart}
8
+ gem.summary = %q{Helps launch unicorn using upstart process management}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "upstart-unicorn-launcher"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = UpstartUnicornLauncher::VERSION
17
+
18
+ gem.add_dependency 'unicorn'
19
+
20
+ gem.add_development_dependency 'rspec'
21
+ gem.add_development_dependency 'curb'
22
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: upstart-unicorn-launcher
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Tom Ward
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-06-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: unicorn
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: curb
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
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
+ description: Launch unicorn with upstart
56
+ email:
57
+ - tom@popdog.net
58
+ executables:
59
+ - upstart-unicorn-launcher
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - .gitignore
64
+ - Gemfile
65
+ - LICENSE
66
+ - README.md
67
+ - Rakefile
68
+ - bin/upstart-unicorn-launcher
69
+ - lib/upstart-unicorn-launcher.rb
70
+ - lib/upstart_unicorn_launcher.rb
71
+ - lib/upstart_unicorn_launcher/version.rb
72
+ - spec/spec_helper.rb
73
+ - spec/templates/test/Gemfile
74
+ - spec/templates/test/config.ru
75
+ - spec/templates/test/unicorn.rb
76
+ - spec/upstart_integration_spec.rb
77
+ - upstart-unicorn-launcher.gemspec
78
+ homepage: ''
79
+ licenses: []
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.0.2
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: Helps launch unicorn using upstart process management
101
+ test_files:
102
+ - spec/spec_helper.rb
103
+ - spec/templates/test/Gemfile
104
+ - spec/templates/test/config.ru
105
+ - spec/templates/test/unicorn.rb
106
+ - spec/upstart_integration_spec.rb