capistrano-unicorn-edge 0.1.4

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ea77bba82cc4703c42b81691b9da9cde60ef05c3
4
+ data.tar.gz: dfe67836b374e0b635bec316a494363d4c8593b4
5
+ SHA512:
6
+ metadata.gz: 87461ffd0a9804cc42da3c3b7b8272ab280612ab6643489f64f34b7d9ce98882823ae7641488e015f8b243283df2c5920b19a288431c55f7a34855774d2da5ee
7
+ data.tar.gz: 3f132926442f85b297fd8df88fb4a172541350952305bd1729c576396a3b1203f9f94aa8259636d6c3e9b7dff1cb50c37a787bfa56076d4c892c918cb95267e2
data/.gitignore ADDED
@@ -0,0 +1,22 @@
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
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in capistrano-unicorn.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Alexander Menzhinsky
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,68 @@
1
+ # Capistrano 3.x :: Unicorn
2
+
3
+ Unicorn specific tasks for Capistrano 3.x
4
+
5
+ ```
6
+ cap unicorn:start # Start unicorn
7
+ cap unicorn:stop # Stop unicorn gracefully (QUIT)
8
+ cap unicorn:shutdown # Stop unicorn immediately (TERM)
9
+ cap unicorn:restart # Restart unicorn, invokes unicorn:restart_usr2
10
+ cap unicorn:restart_hup # Restart unicorn, when preload_app is false (HUP)
11
+ cap unicorn:restart_usr2 # Restart unicorn, when before_fork hook is set and preload_app is true (USR2)
12
+ cap unicorn:restart_usr2_quit # Restart unicorn, when before_fork hook is not set and preload_app is true (USR2 + QUIT)
13
+ cap unicorn:add_worker[count] # Add a worker (TTIN)
14
+ cap unicorn:remove_worker[count] # Remove a worker (TTOU)
15
+ cap unicorn:stop_workers # Stop all workers but keep the master running (WINCH)
16
+ cap unicorn:reopen_logs # Reopen all logs owned by the master and all workers (USR1)
17
+ ```
18
+
19
+ ## Installation
20
+
21
+ Add this line to your application's Gemfile:
22
+
23
+ ```ruby
24
+ gem 'capistrano-unicorn-edge', require: false, group: :development
25
+ ```
26
+
27
+ And then execute:
28
+ ```
29
+ $ bundle
30
+ ```
31
+
32
+ Or install it yourself as:
33
+ ```
34
+ $ gem install capistrano-unicorn-edge
35
+ ```
36
+
37
+ ## Usage
38
+
39
+ Require in `Capfile` to use tasks:
40
+ ```ruby
41
+ require 'capistrano/unicorn'
42
+ ```
43
+
44
+ Configurable options:
45
+ ```ruby
46
+ set :unicorn_pid, -> { current_path.join('tmp/pids/unicorn.pid') } # this is default
47
+ set :unicorn_config, -> { current_path.join("config/unicorn/#{fetch(:rails_env)}.rb") } # this is default
48
+ set :unicorn_roles, :app # this is default
49
+ set :unicorn_options, '' # this is default
50
+ set :unicorn_restart_delay, 5 # this is default
51
+ set :unicorn_rack_env, :deployment # this is default
52
+ set :unicorn_restart_method, :restart_usr2 # this is default
53
+ ```
54
+
55
+ Everything should work **out-of-box** but you need to **set up unicorn's config**. (see an example `examples/unicorn.rb`).
56
+
57
+ There are three different ways to restart server:
58
+ * `:restart_hup` reloads config file and gracefully restart all workers, if `preload_app` is true, then application code changes will have no effect
59
+ * `:restart_usr2_quit` re-execute the running binary and kill old instance in a time interval specified in `:unicorn_restart_delay`, but this method can't be absolutely reliable
60
+ * `:restart_usr2` the same as above but `before_fork` hook which kills old instance has to be set, default and the best choice
61
+
62
+ ## Contributing
63
+
64
+ 1. Fork it ( https://github.com/amenzhinsky/capistrano-unicorn-edge/fork )
65
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
66
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
67
+ 4. Push to the branch (`git push origin my-new-feature`)
68
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "capistrano-unicorn-edge"
7
+ spec.version = "0.1.4"
8
+ spec.authors = ["Alexander Menzhinsky"]
9
+ spec.email = ["amenzhinsky@gmail.com"]
10
+ spec.summary = %q{Unicorn support for Capistrano 3.x}
11
+ spec.description = %q{Unicorn support for Capistrano 3.x}
12
+ spec.homepage = "https://github.com/amenzhinsky/capistrano-unicorn-edge"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency 'capistrano', '~> 3.1'
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.6"
23
+ spec.add_development_dependency "rake"
24
+ end
@@ -0,0 +1,52 @@
1
+ # Set your full path to application.
2
+ app_path = '/home/deploy/web-app/current'
3
+
4
+ # Set unicorn options
5
+ worker_processes 2
6
+ preload_app true
7
+ check_client_connection false
8
+ timeout 30
9
+
10
+ listen "#{app_path}/tmp/sockets/unicorn.sock", backlog: 64
11
+ listen 8888, tcp_nopush: true
12
+
13
+ # Spawn unicorn master worker for user deploy (group: deploy)
14
+ user 'deploy', 'deploy'
15
+
16
+ # Fill path to your app
17
+ working_directory app_path
18
+
19
+ # Log everything to one file
20
+ stderr_path "#{app_path}/log/unicorn.log"
21
+ stdout_path "#{app_path}/log/unicorn.log"
22
+
23
+ # Set master PID location
24
+ pid "#{app_path}/tmp/pids/unicorn.pid"
25
+
26
+ before_fork do |server, worker|
27
+ ##
28
+ # When sent a USR2, Unicorn will suffix its pidfile with .oldbin and
29
+ # immediately start loading up a new version of itself (loaded with a new
30
+ # version of our app). When this new Unicorn is completely loaded
31
+ # it will begin spawning workers. The first worker spawned will check to
32
+ # see if an .oldbin pidfile exists. If so, this means we've just booted up
33
+ # a new Unicorn and need to tell the old one that it can now die. To do so
34
+ # we send it a QUIT.
35
+ #
36
+ # Using this method we get 0 downtime deploys.
37
+ ActiveRecord::Base.connection.disconnect!
38
+
39
+ old_pid = "#{server.config[:pid]}.oldbin"
40
+
41
+ if File.exists?(old_pid) && server.pid != old_pid
42
+ begin
43
+ Process.kill("QUIT", File.read(old_pid).to_i)
44
+ rescue Errno::ENOENT, Errno::ESRCH
45
+ # someone else did our job for us
46
+ end
47
+ end
48
+ end
49
+
50
+ after_fork do |server, worker|
51
+ ActiveRecord::Base.establish_connection
52
+ end
@@ -0,0 +1,124 @@
1
+ namespace :unicorn do
2
+ desc 'Start unicorn'
3
+ task :start do
4
+ on roles(fetch(:unicorn_roles)) do
5
+ unicorn_start unless unicorn_is_running?
6
+ end
7
+ end
8
+
9
+ desc 'Stop unicorn gracefully (QUIT)'
10
+ task :stop do
11
+ on roles(fetch(:unicorn_roles)) do
12
+ unicorn_send_signal(:QUIT) if unicorn_is_running?
13
+ end
14
+ end
15
+
16
+ desc 'Stop unicorn immediately (TERM)'
17
+ task :shutdown do
18
+ on roles(fetch(:unicorn_roles)) do
19
+ unicorn_send_signal('TERM') if unicorn_is_running?
20
+ end
21
+ end
22
+
23
+ desc 'Restart unicorn'
24
+ task :restart do
25
+ invoke "unicorn:#{fetch(:unicorn_restart_method)}"
26
+ end
27
+
28
+ desc 'Restart unicorn, when preload_app is false (HUP)'
29
+ task :restart_hup do
30
+ on roles(fetch(:unicorn_roles)) do
31
+ if unicorn_is_running?
32
+ unicorn_send_signal(:HUP)
33
+ else
34
+ unicorn_start
35
+ end
36
+ end
37
+ end
38
+
39
+ desc 'Restart unicorn, when before_fork hook is set and preload_app is true (USR2)'
40
+ task :restart_usr2 do
41
+ on roles(fetch(:unicorn_roles)) do
42
+ if unicorn_is_running?
43
+ unicorn_send_signal(:USR2)
44
+ else
45
+ unicorn_start
46
+ end
47
+ end
48
+ end
49
+
50
+ desc 'Restart unicorn, when before_fork hook is not set and preload_app is true (USR2 + QUIT)'
51
+ task :restart_usr2_quit do
52
+ on roles(fetch(:unicorn_roles)) do
53
+ if unicorn_is_running?
54
+ unicorn_send_signal(:USR2)
55
+
56
+ execute :sleep, fetch(:unicorn_restart_delay)
57
+
58
+ if unicorn_is_running?(unicorn_old_pid)
59
+ unicorn_send_signal(:QUIT, unicorn_old_pid)
60
+ end
61
+ else
62
+ unicorn_start
63
+ end
64
+ end
65
+ end
66
+
67
+ desc 'Add a worker (TTIN)'
68
+ task :add_worker, :count do |_, args|
69
+ on roles(fetch(:unicorn_roles)) do
70
+ if unicorn_is_running?
71
+ args.fetch(:count, 1).to_i.times do
72
+ unicorn_send_signal(:TTIN)
73
+ end
74
+ else
75
+ error 'unicorn is not running'
76
+ end
77
+ end
78
+ end
79
+
80
+ desc 'Remove a worker (TTOU)'
81
+ task :remove_worker, :count do |_, args|
82
+ on roles(fetch(:unicorn_roles)) do
83
+ if unicorn_is_running?
84
+ args.fetch(:count, 1).to_i.times do
85
+ unicorn_send_signal(:TTOU)
86
+ end
87
+ else
88
+ error 'unicorn is not running'
89
+ end
90
+ end
91
+ end
92
+
93
+ desc 'Stop all workers but keep the master running (WINCH)'
94
+ task :stop_workers do
95
+ if unicorn_is_running?
96
+ unicorn_send_signal(:WINCH)
97
+ else
98
+ error 'unicorn is not running'
99
+ end
100
+ end
101
+
102
+ desc 'Reopen all logs owned by the master and all workers (USR1)'
103
+ task :reopen_logs do
104
+ if unicorn_is_running?
105
+ unicorn_send_signal(:USR1)
106
+ else
107
+ error 'unicorn is not running'
108
+ end
109
+ end
110
+ end
111
+
112
+ namespace :load do
113
+ task :defaults do
114
+ set :unicorn_pid, -> { current_path.join('tmp/pids/unicorn.pid') }
115
+ set :unicorn_config, -> { current_path.join("config/unicorn/#{fetch(:rails_env)}.rb") }
116
+ set :unicorn_roles, :app
117
+ set :unicorn_options, ''
118
+ set :unicorn_restart_delay, 5
119
+ set :unicorn_rack_env, :deployment
120
+ set :unicorn_restart_method, :restart_usr2
121
+ end
122
+ end
123
+
124
+ after 'deploy:published', 'unicorn:restart'
@@ -0,0 +1,23 @@
1
+ def unicorn_is_running?(pidfile = fetch(:unicorn_pid))
2
+ test "[[ -e #{pidfile} ]] && $(kill -0 $(cat #{pidfile}) &> /dev/null)"
3
+ end
4
+
5
+ def unicorn_start
6
+ within release_path do
7
+ with rails_env: fetch(:rails_env) do
8
+ execute :bundle, 'exec', 'unicorn', '-c', fetch(:unicorn_config),
9
+ '-E', fetch(:unicorn_rack_env),
10
+ '-D', fetch(:unicorn_options)
11
+ end
12
+ end
13
+ end
14
+
15
+ def unicorn_old_pid
16
+ "#{fetch(:unicorn_pid)}.oldbin"
17
+ end
18
+
19
+ def unicorn_send_signal(signal, pidfile = fetch(:unicorn_pid))
20
+ execute :kill, "-#{signal}", capture(:cat, pidfile)
21
+ end
22
+
23
+ load File.expand_path('../tasks/unicorn.cap', __FILE__)
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capistrano-unicorn-edge
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.4
5
+ platform: ruby
6
+ authors:
7
+ - Alexander Menzhinsky
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capistrano
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
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: Unicorn support for Capistrano 3.x
56
+ email:
57
+ - amenzhinsky@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - capistrano-unicorn.gemspec
68
+ - examples/unicorn.rb
69
+ - lib/capistrano/tasks/unicorn.cap
70
+ - lib/capistrano/unicorn.rb
71
+ homepage: https://github.com/amenzhinsky/capistrano-unicorn-edge
72
+ licenses:
73
+ - MIT
74
+ metadata: {}
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubyforge_project:
91
+ rubygems_version: 2.2.2
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: Unicorn support for Capistrano 3.x
95
+ test_files: []