capistrano-sidekiq 0.20.0 → 1.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +101 -0
- data/README.md +7 -4
- data/capistrano-sidekiq.gemspec +1 -1
- data/lib/capistrano/sidekiq.rb +1 -5
- data/lib/capistrano/sidekiq/monit.rb +1 -2
- data/lib/capistrano/sidekiq/version.rb +1 -3
- data/lib/capistrano/tasks/monit.rake +33 -7
- data/lib/capistrano/tasks/sidekiq.rake +106 -149
- data/lib/generators/capistrano/sidekiq/monit/templates/sidekiq_monit.conf.erb +1 -1
- metadata +3 -4
- data/CHANGELOG +0 -28
- data/lib/capistrano/tasks/capistrano2.rb +0 -147
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32880c1c6b9be519c9495ac2c5d96339b1349c0d
|
4
|
+
data.tar.gz: e4957a5475c6b66ca3834c7ebfce013d944df4a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0229b5c4bdcc2504750737b61c8cc1960ff5f1e45f1d0ef19e61a38678862530ef0f1ae563bbc16d93e3be1a23ee0e0ae86c8d348de93c37f52d1b4ed6907883'
|
7
|
+
data.tar.gz: 651c4e097370eb64cf1a5a695982783522a8804a3a1282552e75a56e36b2fc43e89d59493e77b320abf46a4ca28053d67de8bc951b409371faa97d8ed7785bc4
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## 1.0.0
|
4
|
+
|
5
|
+
- Prepend underscore before service name index @Tensho
|
6
|
+
- Convert CHANGELOG to Markdown @Tensho
|
7
|
+
- Drop support for capistrano 2.0 @Tensho
|
8
|
+
- *BREAKING CHANGE* If people used custom monit template, they should adjust it to use pid_files variable instead of processes_pids. @Tensho
|
9
|
+
|
10
|
+
## 0.20.0
|
11
|
+
|
12
|
+
- Use new capistrano DSL for reenable tasks @Tensho
|
13
|
+
|
14
|
+
## 0.10.0
|
15
|
+
|
16
|
+
- Fix Monit tasks
|
17
|
+
- `sidekiq:stop` task perpertually callable @Tensho
|
18
|
+
|
19
|
+
## 0.5.4
|
20
|
+
|
21
|
+
- Add support for custom count of processes per host in monit task @okoriko
|
22
|
+
|
23
|
+
## 0.5.3
|
24
|
+
|
25
|
+
- Custom count of processes per each host
|
26
|
+
|
27
|
+
## 0.5.0
|
28
|
+
|
29
|
+
- Multiple processes @mrsimo
|
30
|
+
|
31
|
+
## 0.3.9
|
32
|
+
|
33
|
+
- Restore daemon flag from Monit template
|
34
|
+
|
35
|
+
## 0.3.8
|
36
|
+
|
37
|
+
- Update monit template: use su instead of sudo / permit all Sidekiq options @bensie
|
38
|
+
- Unmonitor monit while deploy @Saicheg
|
39
|
+
|
40
|
+
## 0.3.7
|
41
|
+
|
42
|
+
- Fix capistrano2 task @tribble
|
43
|
+
- Run Sidekiq as daemon from Monit @dpaluy
|
44
|
+
|
45
|
+
## 0.3.5
|
46
|
+
|
47
|
+
- Added `:sidekiq_tag` for capistrano 2 @OscarBarrett
|
48
|
+
|
49
|
+
## 0.3.4
|
50
|
+
|
51
|
+
- Fix bug in `sidekiq:start` for capistrano 2 task
|
52
|
+
|
53
|
+
## 0.3.3
|
54
|
+
|
55
|
+
- `sidekiq:restart` after `deploy:restart` added to default hooks
|
56
|
+
|
57
|
+
## 0.3.2
|
58
|
+
|
59
|
+
- `:sidekiq_queue` accept an array
|
60
|
+
|
61
|
+
## 0.3.1
|
62
|
+
|
63
|
+
- Fix logs @rottman
|
64
|
+
- Add concurrency option support @ungsophy
|
65
|
+
|
66
|
+
## 0.3.0
|
67
|
+
|
68
|
+
- Fix monit task @andreygerasimchuk
|
69
|
+
|
70
|
+
## 0.2.9
|
71
|
+
|
72
|
+
- Check if current directory exist @alexdunae
|
73
|
+
|
74
|
+
## 0.2.8
|
75
|
+
|
76
|
+
- Added `:sidekiq_queue` & `:sidekiq_config`
|
77
|
+
|
78
|
+
## 0.2.7
|
79
|
+
|
80
|
+
- Signal usage @penso
|
81
|
+
|
82
|
+
## 0.2.6
|
83
|
+
|
84
|
+
- `sidekiq:start` check if sidekiq is running
|
85
|
+
|
86
|
+
## 0.2.5
|
87
|
+
|
88
|
+
- Bug fixes
|
89
|
+
|
90
|
+
## 0.2.4
|
91
|
+
|
92
|
+
- Fast deploy with `:sidekiq_run_in_background`
|
93
|
+
|
94
|
+
## 0.2.3
|
95
|
+
|
96
|
+
- Added monit tasks (alpha)
|
97
|
+
|
98
|
+
## 0.2.0
|
99
|
+
|
100
|
+
- Added `sidekiq:rolling_restart` @jlecour
|
101
|
+
|
data/README.md
CHANGED
@@ -41,16 +41,19 @@ Configurable options, shown here with defaults:
|
|
41
41
|
:sidekiq_config => nil # if you have a config/sidekiq.yml, do not forget to set this.
|
42
42
|
:sidekiq_queue => nil
|
43
43
|
:sidekiq_timeout => 10
|
44
|
-
:
|
44
|
+
:sidekiq_roles => :app
|
45
45
|
:sidekiq_processes => 1
|
46
46
|
:sidekiq_options_per_process => nil
|
47
47
|
:sidekiq_concurrency => nil
|
48
|
+
# sidekiq monit
|
48
49
|
:sidekiq_monit_templates_path => 'config/deploy/templates'
|
49
50
|
:sidekiq_monit_conf_dir => '/etc/monit/conf.d'
|
50
51
|
:sidekiq_monit_use_sudo => true
|
51
52
|
:monit_bin => '/usr/bin/monit'
|
52
53
|
:sidekiq_monit_default_hooks => true
|
53
|
-
:
|
54
|
+
:sidekiq_monit_group => nil
|
55
|
+
:sidekiq_service_name => "sidekiq_#{fetch(:application)}_#{fetch(:sidekiq_env)}" + (index ? "_#{index}" : '')
|
56
|
+
|
54
57
|
:sidekiq_cmd => "#{fetch(:bundle_cmd, "bundle")} exec sidekiq" # Only for capistrano2.5
|
55
58
|
:sidekiqctl_cmd => "#{fetch(:bundle_cmd, "bundle")} exec sidekiqctl" # Only for capistrano2.5
|
56
59
|
:sidekiq_user => nil #user to run sidekiq as
|
@@ -74,12 +77,12 @@ and `low`:
|
|
74
77
|
set :sidekiq_options_per_process, ["--queue high", "--queue default --queue low"]
|
75
78
|
```
|
76
79
|
|
77
|
-
## Different number of processes per
|
80
|
+
## Different number of processes per role
|
78
81
|
|
79
82
|
You can configure how many processes you want to run on each host next way:
|
80
83
|
|
81
84
|
```ruby
|
82
|
-
set :
|
85
|
+
set :sidekiq_roles, [:sidekiq_small, :sidekiq_big]
|
83
86
|
set :sidekiq_small_processes, 1
|
84
87
|
set :sidekiq_big_processes, 4
|
85
88
|
server 'example-small.com', roles: [:sidekiq_small]
|
data/capistrano-sidekiq.gemspec
CHANGED
@@ -5,7 +5,7 @@ require 'capistrano/sidekiq/version'
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = 'capistrano-sidekiq'
|
8
|
-
spec.version = Capistrano::
|
8
|
+
spec.version = Capistrano::SidekiqVERSION
|
9
9
|
spec.authors = ['Abdelkader Boudih']
|
10
10
|
spec.email = ['terminale@gmail.com']
|
11
11
|
spec.summary = %q{Sidekiq integration for Capistrano}
|
data/lib/capistrano/sidekiq.rb
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
|
2
|
-
load File.expand_path('../../tasks/monit.rake', __FILE__)
|
1
|
+
load File.expand_path('../../tasks/monit.rake', __FILE__)
|
@@ -5,6 +5,7 @@ namespace :load do
|
|
5
5
|
set :monit_bin, '/usr/bin/monit'
|
6
6
|
set :sidekiq_monit_default_hooks, true
|
7
7
|
set :sidekiq_monit_templates_path, 'config/deploy/templates'
|
8
|
+
set :sidekiq_monit_group, nil
|
8
9
|
end
|
9
10
|
end
|
10
11
|
|
@@ -26,7 +27,7 @@ namespace :sidekiq do
|
|
26
27
|
|
27
28
|
desc 'Config Sidekiq monit-service'
|
28
29
|
task :config do
|
29
|
-
on roles(fetch(:
|
30
|
+
on roles(fetch(:sidekiq_roles)) do |role|
|
30
31
|
@role = role
|
31
32
|
upload_sidekiq_template 'sidekiq_monit', "#{fetch(:tmp_dir)}/monit.conf", @role
|
32
33
|
|
@@ -39,7 +40,7 @@ namespace :sidekiq do
|
|
39
40
|
|
40
41
|
desc 'Monitor Sidekiq monit-service'
|
41
42
|
task :monitor do
|
42
|
-
on roles(fetch(:
|
43
|
+
on roles(fetch(:sidekiq_roles)) do
|
43
44
|
fetch(:sidekiq_processes).times do |idx|
|
44
45
|
begin
|
45
46
|
sudo_if_needed "#{fetch(:monit_bin)} monitor #{sidekiq_service_name(idx)}"
|
@@ -53,7 +54,7 @@ namespace :sidekiq do
|
|
53
54
|
|
54
55
|
desc 'Unmonitor Sidekiq monit-service'
|
55
56
|
task :unmonitor do
|
56
|
-
on roles(fetch(:
|
57
|
+
on roles(fetch(:sidekiq_roles)) do
|
57
58
|
fetch(:sidekiq_processes).times do |idx|
|
58
59
|
begin
|
59
60
|
sudo_if_needed "#{fetch(:monit_bin)} unmonitor #{sidekiq_service_name(idx)}"
|
@@ -66,7 +67,7 @@ namespace :sidekiq do
|
|
66
67
|
|
67
68
|
desc 'Start Sidekiq monit-service'
|
68
69
|
task :start do
|
69
|
-
on roles(fetch(:
|
70
|
+
on roles(fetch(:sidekiq_roles)) do
|
70
71
|
fetch(:sidekiq_processes).times do |idx|
|
71
72
|
sudo_if_needed "#{fetch(:monit_bin)} start #{sidekiq_service_name(idx)}"
|
72
73
|
end
|
@@ -75,7 +76,7 @@ namespace :sidekiq do
|
|
75
76
|
|
76
77
|
desc 'Stop Sidekiq monit-service'
|
77
78
|
task :stop do
|
78
|
-
on roles(fetch(:
|
79
|
+
on roles(fetch(:sidekiq_roles)) do
|
79
80
|
fetch(:sidekiq_processes).times do |idx|
|
80
81
|
sudo_if_needed "#{fetch(:monit_bin)} stop #{sidekiq_service_name(idx)}"
|
81
82
|
end
|
@@ -84,7 +85,7 @@ namespace :sidekiq do
|
|
84
85
|
|
85
86
|
desc 'Restart Sidekiq monit-service'
|
86
87
|
task :restart do
|
87
|
-
on roles(fetch(:
|
88
|
+
on roles(fetch(:sidekiq_roles)) do
|
88
89
|
fetch(:sidekiq_processes).times do |idx|
|
89
90
|
sudo_if_needed"#{fetch(:monit_bin)} restart #{sidekiq_service_name(idx)}"
|
90
91
|
end
|
@@ -92,7 +93,7 @@ namespace :sidekiq do
|
|
92
93
|
end
|
93
94
|
|
94
95
|
def sidekiq_service_name(index=nil)
|
95
|
-
fetch(:sidekiq_service_name, "sidekiq_#{fetch(:application)}_#{fetch(:sidekiq_env)}") + index
|
96
|
+
fetch(:sidekiq_service_name, "sidekiq_#{fetch(:application)}_#{fetch(:sidekiq_env)}") + (index ? "_#{index}" : '')
|
96
97
|
end
|
97
98
|
|
98
99
|
def sidekiq_config
|
@@ -137,5 +138,30 @@ namespace :sidekiq do
|
|
137
138
|
fetch(:sidekiq_monit_use_sudo)
|
138
139
|
end
|
139
140
|
|
141
|
+
def upload_sidekiq_template(from, to, role)
|
142
|
+
template = sidekiq_template(from, role)
|
143
|
+
upload!(StringIO.new(ERB.new(template).result(binding)), to)
|
144
|
+
end
|
145
|
+
|
146
|
+
def sidekiq_template(name, role)
|
147
|
+
local_template_directory = fetch(:sidekiq_monit_templates_path)
|
148
|
+
|
149
|
+
search_paths = [
|
150
|
+
"#{name}-#{role.hostname}-#{fetch(:stage)}.erb",
|
151
|
+
"#{name}-#{role.hostname}.erb",
|
152
|
+
"#{name}-#{fetch(:stage)}.erb",
|
153
|
+
"#{name}.erb"
|
154
|
+
].map { |filename| File.join(local_template_directory, filename) }
|
155
|
+
|
156
|
+
global_search_path = File.expand_path(
|
157
|
+
File.join(*%w[.. .. .. generators capistrano sidekiq monit templates], "#{name}.conf.erb"),
|
158
|
+
__FILE__
|
159
|
+
)
|
160
|
+
|
161
|
+
search_paths << global_search_path
|
162
|
+
|
163
|
+
template_path = search_paths.detect { |path| File.file?(path) }
|
164
|
+
File.read(template_path)
|
165
|
+
end
|
140
166
|
end
|
141
167
|
end
|
@@ -1,15 +1,15 @@
|
|
1
1
|
namespace :load do
|
2
2
|
task :defaults do
|
3
|
-
set :sidekiq_default_hooks,
|
3
|
+
set :sidekiq_default_hooks, true
|
4
4
|
|
5
5
|
set :sidekiq_pid, -> { File.join(shared_path, 'tmp', 'pids', 'sidekiq.pid') }
|
6
6
|
set :sidekiq_env, -> { fetch(:rack_env, fetch(:rails_env, fetch(:stage))) }
|
7
7
|
set :sidekiq_log, -> { File.join(shared_path, 'log', 'sidekiq.log') }
|
8
|
-
set :sidekiq_timeout,
|
9
|
-
set :
|
10
|
-
set :sidekiq_processes,
|
11
|
-
set :sidekiq_options_per_process,
|
12
|
-
set :sidekiq_user,
|
8
|
+
set :sidekiq_timeout, 10
|
9
|
+
set :sidekiq_roles, :app
|
10
|
+
set :sidekiq_processes, 1
|
11
|
+
set :sidekiq_options_per_process, nil
|
12
|
+
set :sidekiq_user, nil
|
13
13
|
# Rbenv, Chruby, and RVM integration
|
14
14
|
set :rbenv_map_bins, fetch(:rbenv_map_bins).to_a.concat(%w(sidekiq sidekiqctl))
|
15
15
|
set :rvm_map_bins, fetch(:rvm_map_bins).to_a.concat(%w(sidekiq sidekiqctl))
|
@@ -29,110 +29,20 @@ namespace :deploy do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
namespace :sidekiq do
|
32
|
-
def for_each_process(reverse = false, &block)
|
33
|
-
pids = processes_pids
|
34
|
-
pids.reverse! if reverse
|
35
|
-
pids.each_with_index do |pid_file, idx|
|
36
|
-
within release_path do
|
37
|
-
yield(pid_file, idx)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def processes_pids
|
43
|
-
pids = []
|
44
|
-
sidekiq_roles = Array(fetch(:sidekiq_role))
|
45
|
-
sidekiq_roles.each do |role|
|
46
|
-
next unless host.roles.include?(role)
|
47
|
-
processes = fetch(:"#{ role }_processes") || fetch(:sidekiq_processes)
|
48
|
-
processes.times do |idx|
|
49
|
-
pids.push fetch(:sidekiq_pid).gsub(/\.pid$/, "-#{idx}.pid")
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
pids
|
54
|
-
end
|
55
|
-
|
56
|
-
def pid_process_exists?(pid_file)
|
57
|
-
pid_file_exists?(pid_file) and test(*("kill -0 $( cat #{pid_file} )").split(' '))
|
58
|
-
end
|
59
|
-
|
60
|
-
def pid_file_exists?(pid_file)
|
61
|
-
test(*("[ -f #{pid_file} ]").split(' '))
|
62
|
-
end
|
63
|
-
|
64
|
-
def stop_sidekiq(pid_file)
|
65
|
-
if fetch(:stop_sidekiq_in_background, fetch(:sidekiq_run_in_background))
|
66
|
-
if fetch(:sidekiq_use_signals)
|
67
|
-
background "kill -TERM `cat #{pid_file}`"
|
68
|
-
else
|
69
|
-
background :sidekiqctl, 'stop', "#{pid_file}", fetch(:sidekiq_timeout)
|
70
|
-
end
|
71
|
-
else
|
72
|
-
execute :sidekiqctl, 'stop', "#{pid_file}", fetch(:sidekiq_timeout)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def quiet_sidekiq(pid_file)
|
77
|
-
if fetch(:sidekiq_use_signals)
|
78
|
-
background "kill -USR1 `cat #{pid_file}`"
|
79
|
-
else
|
80
|
-
begin
|
81
|
-
execute :sidekiqctl, 'quiet', "#{pid_file}"
|
82
|
-
rescue SSHKit::Command::Failed
|
83
|
-
# If gems are not installed eq(first deploy) and sidekiq_default_hooks as active
|
84
|
-
warn 'sidekiqctl not found (ignore if this is the first deploy)'
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def start_sidekiq(pid_file, idx = 0)
|
90
|
-
args = []
|
91
|
-
args.push "--index #{idx}"
|
92
|
-
args.push "--pidfile #{pid_file}"
|
93
|
-
args.push "--environment #{fetch(:sidekiq_env)}"
|
94
|
-
args.push "--logfile #{fetch(:sidekiq_log)}" if fetch(:sidekiq_log)
|
95
|
-
args.push "--require #{fetch(:sidekiq_require)}" if fetch(:sidekiq_require)
|
96
|
-
args.push "--tag #{fetch(:sidekiq_tag)}" if fetch(:sidekiq_tag)
|
97
|
-
Array(fetch(:sidekiq_queue)).each do |queue|
|
98
|
-
args.push "--queue #{queue}"
|
99
|
-
end
|
100
|
-
args.push "--config #{fetch(:sidekiq_config)}" if fetch(:sidekiq_config)
|
101
|
-
args.push "--concurrency #{fetch(:sidekiq_concurrency)}" if fetch(:sidekiq_concurrency)
|
102
|
-
if process_options = fetch(:sidekiq_options_per_process)
|
103
|
-
args.push process_options[idx]
|
104
|
-
end
|
105
|
-
# use sidekiq_options for special options
|
106
|
-
args.push fetch(:sidekiq_options) if fetch(:sidekiq_options)
|
107
|
-
|
108
|
-
if defined?(JRUBY_VERSION)
|
109
|
-
args.push '>/dev/null 2>&1 &'
|
110
|
-
warn 'Since JRuby doesn\'t support Process.daemon, Sidekiq will not be running as a daemon.'
|
111
|
-
else
|
112
|
-
args.push '--daemon'
|
113
|
-
end
|
114
|
-
|
115
|
-
if fetch(:start_sidekiq_in_background, fetch(:sidekiq_run_in_background))
|
116
|
-
background :sidekiq, args.compact.join(' ')
|
117
|
-
else
|
118
|
-
execute :sidekiq, args.compact.join(' ')
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
32
|
task :add_default_hooks do
|
123
|
-
after 'deploy:starting',
|
124
|
-
after 'deploy:updated',
|
125
|
-
after 'deploy:reverted',
|
33
|
+
after 'deploy:starting', 'sidekiq:quiet'
|
34
|
+
after 'deploy:updated', 'sidekiq:stop'
|
35
|
+
after 'deploy:reverted', 'sidekiq:stop'
|
126
36
|
after 'deploy:published', 'sidekiq:start'
|
127
37
|
end
|
128
38
|
|
129
|
-
desc 'Quiet sidekiq (stop
|
39
|
+
desc 'Quiet sidekiq (stop fetching new tasks from Redis)'
|
130
40
|
task :quiet do
|
131
|
-
on roles fetch(:
|
41
|
+
on roles fetch(:sidekiq_roles) do |role|
|
132
42
|
switch_user(role) do
|
133
|
-
if test("[ -d #{release_path} ]")
|
134
|
-
|
135
|
-
if
|
43
|
+
if test("[ -d #{release_path} ]")
|
44
|
+
each_process_with_index(reverse: true) do |pid_file, idx|
|
45
|
+
if pid_file_exists?(pid_file) && process_exists?(pid_file)
|
136
46
|
quiet_sidekiq(pid_file)
|
137
47
|
end
|
138
48
|
end
|
@@ -141,13 +51,13 @@ namespace :sidekiq do
|
|
141
51
|
end
|
142
52
|
end
|
143
53
|
|
144
|
-
desc 'Stop sidekiq'
|
54
|
+
desc 'Stop sidekiq (graceful shutdown within timeout, put unfinished tasks back to Redis)'
|
145
55
|
task :stop do
|
146
|
-
on roles fetch(:
|
56
|
+
on roles fetch(:sidekiq_roles) do |role|
|
147
57
|
switch_user(role) do
|
148
58
|
if test("[ -d #{release_path} ]")
|
149
|
-
|
150
|
-
if
|
59
|
+
each_process_with_index(reverse: true) do |pid_file, idx|
|
60
|
+
if pid_file_exists?(pid_file) && process_exists?(pid_file)
|
151
61
|
stop_sidekiq(pid_file)
|
152
62
|
end
|
153
63
|
end
|
@@ -158,10 +68,12 @@ namespace :sidekiq do
|
|
158
68
|
|
159
69
|
desc 'Start sidekiq'
|
160
70
|
task :start do
|
161
|
-
on roles fetch(:
|
71
|
+
on roles fetch(:sidekiq_roles) do |role|
|
162
72
|
switch_user(role) do
|
163
|
-
|
164
|
-
|
73
|
+
each_process_with_index do |pid_file, idx|
|
74
|
+
unless pid_file_exists?(pid_file) && process_exists?(pid_file)
|
75
|
+
start_sidekiq(pid_file, idx)
|
76
|
+
end
|
165
77
|
end
|
166
78
|
end
|
167
79
|
end
|
@@ -175,10 +87,10 @@ namespace :sidekiq do
|
|
175
87
|
|
176
88
|
desc 'Rolling-restart sidekiq'
|
177
89
|
task :rolling_restart do
|
178
|
-
on roles fetch(:
|
90
|
+
on roles fetch(:sidekiq_roles) do |role|
|
179
91
|
switch_user(role) do
|
180
|
-
|
181
|
-
if
|
92
|
+
each_process_with_index(true) do |pid_file, idx|
|
93
|
+
if pid_file_exists?(pid_file) && process_exists?(pid_file)
|
182
94
|
stop_sidekiq(pid_file)
|
183
95
|
end
|
184
96
|
start_sidekiq(pid_file, idx)
|
@@ -187,26 +99,28 @@ namespace :sidekiq do
|
|
187
99
|
end
|
188
100
|
end
|
189
101
|
|
190
|
-
|
102
|
+
desc 'Delete any pid file not in use'
|
191
103
|
task :cleanup do
|
192
|
-
on roles fetch(:
|
104
|
+
on roles fetch(:sidekiq_roles) do |role|
|
193
105
|
switch_user(role) do
|
194
|
-
|
195
|
-
|
196
|
-
|
106
|
+
each_process_with_index do |pid_file, idx|
|
107
|
+
unless process_exists?(pid_file)
|
108
|
+
if pid_file_exists?(pid_file)
|
109
|
+
execute "rm #{pid_file}"
|
110
|
+
end
|
197
111
|
end
|
198
112
|
end
|
199
113
|
end
|
200
114
|
end
|
201
115
|
end
|
202
116
|
|
203
|
-
# TODO
|
117
|
+
# TODO: Don't start if all processes are off, raise warning.
|
204
118
|
desc 'Respawn missing sidekiq processes'
|
205
119
|
task :respawn do
|
206
120
|
invoke 'sidekiq:cleanup'
|
207
|
-
on roles fetch(:
|
121
|
+
on roles fetch(:sidekiq_roles) do |role|
|
208
122
|
switch_user(role) do
|
209
|
-
|
123
|
+
each_process_with_index do |pid_file, idx|
|
210
124
|
unless pid_file_exists?(pid_file)
|
211
125
|
start_sidekiq(pid_file, idx)
|
212
126
|
end
|
@@ -215,6 +129,75 @@ namespace :sidekiq do
|
|
215
129
|
end
|
216
130
|
end
|
217
131
|
|
132
|
+
def each_process_with_index(reverse: false)
|
133
|
+
_pid_files = pid_files
|
134
|
+
_pid_files.reverse! if reverse
|
135
|
+
_pid_files.each_with_index do |pid_file, idx|
|
136
|
+
within release_path do
|
137
|
+
yield(pid_file, idx)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def pid_files
|
143
|
+
sidekiq_roles = Array(fetch(:sidekiq_roles))
|
144
|
+
sidekiq_roles.select! { |role| host.roles.include?(role) }
|
145
|
+
sidekiq_roles.flat_map do |role|
|
146
|
+
processes = fetch(:"#{ role }_processes") || fetch(:sidekiq_processes)
|
147
|
+
Array.new(processes) { |idx| fetch(:sidekiq_pid).gsub(/\.pid$/, "-#{idx}.pid") }
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def pid_file_exists?(pid_file)
|
152
|
+
test(*("[ -f #{pid_file} ]").split(' '))
|
153
|
+
end
|
154
|
+
|
155
|
+
def process_exists?(pid_file)
|
156
|
+
test(*("kill -0 $( cat #{pid_file} )").split(' '))
|
157
|
+
end
|
158
|
+
|
159
|
+
def quiet_sidekiq(pid_file)
|
160
|
+
begin
|
161
|
+
execute :sidekiqctl, 'quiet', "#{pid_file}"
|
162
|
+
rescue SSHKit::Command::Failed
|
163
|
+
# If gems are not installed (first deploy) and sidekiq_default_hooks is active
|
164
|
+
warn 'sidekiqctl not found (ignore if this is the first deploy)'
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def stop_sidekiq(pid_file)
|
169
|
+
execute :sidekiqctl, 'stop', "#{pid_file}", fetch(:sidekiq_timeout)
|
170
|
+
end
|
171
|
+
|
172
|
+
def start_sidekiq(pid_file, idx = 0)
|
173
|
+
args = []
|
174
|
+
args.push "--index #{idx}"
|
175
|
+
args.push "--pidfile #{pid_file}"
|
176
|
+
args.push "--environment #{fetch(:sidekiq_env)}"
|
177
|
+
args.push "--logfile #{fetch(:sidekiq_log)}" if fetch(:sidekiq_log)
|
178
|
+
args.push "--require #{fetch(:sidekiq_require)}" if fetch(:sidekiq_require)
|
179
|
+
args.push "--tag #{fetch(:sidekiq_tag)}" if fetch(:sidekiq_tag)
|
180
|
+
Array(fetch(:sidekiq_queue)).each do |queue|
|
181
|
+
args.push "--queue #{queue}"
|
182
|
+
end
|
183
|
+
args.push "--config #{fetch(:sidekiq_config)}" if fetch(:sidekiq_config)
|
184
|
+
args.push "--concurrency #{fetch(:sidekiq_concurrency)}" if fetch(:sidekiq_concurrency)
|
185
|
+
if process_options = fetch(:sidekiq_options_per_process)
|
186
|
+
args.push process_options[idx]
|
187
|
+
end
|
188
|
+
# use sidekiq_options for special options
|
189
|
+
args.push fetch(:sidekiq_options) if fetch(:sidekiq_options)
|
190
|
+
|
191
|
+
if defined?(JRUBY_VERSION)
|
192
|
+
args.push '>/dev/null 2>&1 &'
|
193
|
+
warn 'Since JRuby doesn\'t support Process.daemon, Sidekiq will not be running as a daemon.'
|
194
|
+
else
|
195
|
+
args.push '--daemon'
|
196
|
+
end
|
197
|
+
|
198
|
+
execute :sidekiq, args.compact.join(' ')
|
199
|
+
end
|
200
|
+
|
218
201
|
def switch_user(role, &block)
|
219
202
|
su_user = sidekiq_user(role)
|
220
203
|
if su_user == role.user
|
@@ -228,35 +211,9 @@ namespace :sidekiq do
|
|
228
211
|
|
229
212
|
def sidekiq_user(role)
|
230
213
|
properties = role.properties
|
231
|
-
properties.fetch(:sidekiq_user) ||
|
214
|
+
properties.fetch(:sidekiq_user) || # local property for sidekiq only
|
232
215
|
fetch(:sidekiq_user) ||
|
233
216
|
properties.fetch(:run_as) || # global property across multiple capistrano gems
|
234
217
|
role.user
|
235
218
|
end
|
236
|
-
|
237
|
-
def upload_sidekiq_template(from, to, role)
|
238
|
-
template = sidekiq_template(from, role)
|
239
|
-
upload!(StringIO.new(ERB.new(template).result(binding)), to)
|
240
|
-
end
|
241
|
-
|
242
|
-
def sidekiq_template(name, role)
|
243
|
-
local_template_directory = fetch(:sidekiq_monit_templates_path)
|
244
|
-
|
245
|
-
search_paths = [
|
246
|
-
"#{name}-#{role.hostname}-#{fetch(:stage)}.erb",
|
247
|
-
"#{name}-#{role.hostname}.erb",
|
248
|
-
"#{name}-#{fetch(:stage)}.erb",
|
249
|
-
"#{name}.erb"
|
250
|
-
].map { |filename| File.join(local_template_directory, filename) }
|
251
|
-
|
252
|
-
global_search_path = File.expand_path(
|
253
|
-
File.join(*%w[.. .. .. generators capistrano sidekiq monit templates], "#{name}.conf.erb"),
|
254
|
-
__FILE__
|
255
|
-
)
|
256
|
-
|
257
|
-
search_paths << global_search_path
|
258
|
-
|
259
|
-
template_path = search_paths.detect { |path| File.file?(path) }
|
260
|
-
File.read(template_path)
|
261
|
-
end
|
262
219
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Monit configuration for Sidekiq : <%= fetch(:application) %>
|
2
|
-
<%
|
2
|
+
<% pid_files.each_with_index do |pid_file, idx| %>
|
3
3
|
check process <%= sidekiq_service_name(idx) %>
|
4
4
|
with pidfile "<%= pid_file %>"
|
5
5
|
start program = "/bin/su - <%= sidekiq_user(@role) %> -c 'cd <%= current_path %> && <%= SSHKit.config.command_map[:sidekiq] %> <%= sidekiq_config %> --index <%= idx %> --pidfile <%= pid_file %> --environment <%= fetch(:sidekiq_env) %> <%= sidekiq_concurrency %> <%= sidekiq_logfile %> <%= sidekiq_require %> <%= sidekiq_queues %> <%= sidekiq_options_per_process[idx] %> -d'" with timeout 30 seconds
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capistrano-sidekiq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Abdelkader Boudih
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: capistrano
|
@@ -46,7 +46,7 @@ extensions: []
|
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
48
|
- ".gitignore"
|
49
|
-
- CHANGELOG
|
49
|
+
- CHANGELOG.md
|
50
50
|
- CONTRIBUTORS.md
|
51
51
|
- Gemfile
|
52
52
|
- LICENSE.txt
|
@@ -57,7 +57,6 @@ files:
|
|
57
57
|
- lib/capistrano/sidekiq.rb
|
58
58
|
- lib/capistrano/sidekiq/monit.rb
|
59
59
|
- lib/capistrano/sidekiq/version.rb
|
60
|
-
- lib/capistrano/tasks/capistrano2.rb
|
61
60
|
- lib/capistrano/tasks/monit.rake
|
62
61
|
- lib/capistrano/tasks/sidekiq.rake
|
63
62
|
- lib/generators/capistrano/sidekiq/monit/template_generator.rb
|
data/CHANGELOG
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
## Changelog
|
2
|
-
- 0.10.0:
|
3
|
-
* Fix Monit tasks
|
4
|
-
* sidekiq:stop task perpertually callable
|
5
|
-
- 0.5.4: Add support for custom count of processes per host in monit task @okoriko
|
6
|
-
- 0.5.3: Custom count of processes per each host
|
7
|
-
- 0.5.0: Multiple processes @mrsimo
|
8
|
-
- 0.3.9: Restore daemon flag from Monit template
|
9
|
-
- 0.3.8:
|
10
|
-
* Update monit template: use su instead of sudo / permit all Sidekiq options @bensie
|
11
|
-
* Unmonitor monit while deploy @Saicheg
|
12
|
-
- 0.3.7:
|
13
|
-
* fix capistrano2 task @tribble
|
14
|
-
* Run Sidekiq as daemon from Monit @dpaluy
|
15
|
-
- 0.3.5: Added :sidekiq_tag for capistrano2 @OscarBarrett
|
16
|
-
- 0.3.4: fix bug in sidekiq:start for capistrano 2 task
|
17
|
-
- 0.3.3: sidekiq:restart after deploy:restart added to default hooks
|
18
|
-
- 0.3.2: :sidekiq_queue accept an array
|
19
|
-
- 0.3.1: Fix logs @rottman, add concurrency option support @ungsophy
|
20
|
-
- 0.3.0: Fix monit task @andreygerasimchuk
|
21
|
-
- 0.2.9: Check if current directory exist @alexdunae
|
22
|
-
- 0.2.8: Added :sidekiq_queue & :sidekiq_config
|
23
|
-
- 0.2.7: Signal usage @penso
|
24
|
-
- 0.2.6: sidekiq:start check if sidekiq is running
|
25
|
-
- 0.2.5: bug fixes
|
26
|
-
- 0.2.4: Fast deploy with :sidekiq_run_in_background
|
27
|
-
- 0.2.3: Added monit tasks (alpha)
|
28
|
-
- 0.2.0: Added sidekiq:rolling_restart - @jlecour
|
@@ -1,147 +0,0 @@
|
|
1
|
-
Capistrano::Configuration.instance.load do
|
2
|
-
|
3
|
-
_cset(:sidekiq_default_hooks) { true }
|
4
|
-
|
5
|
-
_cset(:sidekiq_pid) { File.join(shared_path, 'pids', 'sidekiq.pid') }
|
6
|
-
_cset(:sidekiq_env) { fetch(:rack_env, fetch(:rails_env, 'production')) }
|
7
|
-
_cset(:sidekiq_tag) { nil }
|
8
|
-
_cset(:sidekiq_log) { File.join(shared_path, 'log', 'sidekiq.log') }
|
9
|
-
|
10
|
-
_cset(:sidekiq_config) { "#{current_path}/config/sidekiq.yml" }
|
11
|
-
_cset(:sidekiq_options) { nil }
|
12
|
-
_cset(:sidekiq_queue) { nil }
|
13
|
-
_cset(:sidekiq_concurrency) { nil }
|
14
|
-
|
15
|
-
_cset(:sidekiq_cmd) { "#{fetch(:bundle_cmd, 'bundle')} exec sidekiq" }
|
16
|
-
_cset(:sidekiqctl_cmd) { "#{fetch(:bundle_cmd, 'bundle')} exec sidekiqctl" }
|
17
|
-
|
18
|
-
_cset(:sidekiq_timeout) { 10 }
|
19
|
-
_cset(:sidekiq_role) { :app }
|
20
|
-
|
21
|
-
_cset(:sidekiq_processes) { 1 }
|
22
|
-
_cset(:sidekiq_options_per_process) { nil }
|
23
|
-
|
24
|
-
_cset(:sidekiq_user) { nil }
|
25
|
-
|
26
|
-
if fetch(:sidekiq_default_hooks)
|
27
|
-
before 'deploy:update_code', 'sidekiq:quiet'
|
28
|
-
after 'deploy:stop', 'sidekiq:stop'
|
29
|
-
after 'deploy:start', 'sidekiq:start'
|
30
|
-
before 'deploy:restart', 'sidekiq:restart'
|
31
|
-
end
|
32
|
-
|
33
|
-
namespace :sidekiq do
|
34
|
-
def for_each_process(sidekiq_role, &block)
|
35
|
-
sidekiq_processes = fetch(:"#{ sidekiq_role }_processes") rescue 1
|
36
|
-
sidekiq_processes.times do |idx|
|
37
|
-
pid_file = fetch(:sidekiq_pid).gsub(/\.pid$/, "-#{idx}.pid")
|
38
|
-
yield(pid_file, idx)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def for_each_role
|
43
|
-
sidekiq_roles = fetch(:sidekiq_role)
|
44
|
-
|
45
|
-
sidekiq_roles = if sidekiq_roles.respond_to?(:to_ary)
|
46
|
-
sidekiq_roles.to_ary
|
47
|
-
else
|
48
|
-
[sidekiq_roles]
|
49
|
-
end
|
50
|
-
|
51
|
-
sidekiq_roles.to_ary.each do |sidekiq_role|
|
52
|
-
puts "executing on ##{ sidekiq_role }" if sidekiq_roles.size > 1
|
53
|
-
yield(sidekiq_role)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def run_as(cmd)
|
58
|
-
opts = {
|
59
|
-
roles: sidekiq_role
|
60
|
-
}
|
61
|
-
su_user = fetch(:sidekiq_user)
|
62
|
-
opts[:shell] = "su - #{su_user}" if su_user
|
63
|
-
run cmd, opts
|
64
|
-
end
|
65
|
-
|
66
|
-
def quiet_process(pid_file, idx, sidekiq_role)
|
67
|
-
run_as "if [ -d #{current_path} ] && [ -f #{pid_file} ] && kill -0 `cat #{pid_file}`> /dev/null 2>&1; then cd #{current_path} && #{fetch(:sidekiqctl_cmd)} quiet #{pid_file} ; else echo 'Sidekiq is not running'; fi"
|
68
|
-
end
|
69
|
-
|
70
|
-
def stop_process(pid_file, idx, sidekiq_role)
|
71
|
-
run_as "if [ -d #{current_path} ] && [ -f #{pid_file} ] && kill -0 `cat #{pid_file}`> /dev/null 2>&1; then cd #{current_path} && #{fetch(:sidekiqctl_cmd)} stop #{pid_file} #{fetch :sidekiq_timeout} ; else echo 'Sidekiq is not running'; fi"
|
72
|
-
end
|
73
|
-
|
74
|
-
def start_process(pid_file, idx, sidekiq_role)
|
75
|
-
args = []
|
76
|
-
args.push "--index #{idx}"
|
77
|
-
args.push "--pidfile #{pid_file}"
|
78
|
-
args.push "--environment #{fetch(:sidekiq_env)}"
|
79
|
-
args.push "--tag #{fetch(:sidekiq_tag)}" if fetch(:sidekiq_tag)
|
80
|
-
args.push "--logfile #{fetch(:sidekiq_log)}" if fetch(:sidekiq_log)
|
81
|
-
args.push "--config #{fetch(:sidekiq_config)}" if fetch(:sidekiq_config)
|
82
|
-
args.push "--concurrency #{fetch(:sidekiq_concurrency)}" if fetch(:sidekiq_concurrency)
|
83
|
-
fetch(:sidekiq_queue).each do |queue|
|
84
|
-
args.push "--queue #{queue}"
|
85
|
-
end if fetch(:sidekiq_queue)
|
86
|
-
|
87
|
-
if process_options = fetch(:sidekiq_options_per_process)
|
88
|
-
args.push process_options[idx]
|
89
|
-
end
|
90
|
-
|
91
|
-
args.push fetch(:sidekiq_options)
|
92
|
-
|
93
|
-
if defined?(JRUBY_VERSION)
|
94
|
-
args.push '>/dev/null 2>&1 &'
|
95
|
-
logger.info 'Since JRuby doesn\'t support Process.daemon, Sidekiq will not be running as a daemon.'
|
96
|
-
else
|
97
|
-
args.push '--daemon'
|
98
|
-
end
|
99
|
-
|
100
|
-
run_as "if [ -d #{current_path} ] && [ ! -f #{pid_file} ] || ! kill -0 `cat #{pid_file}` > /dev/null 2>&1; then cd #{current_path} ; #{fetch(:sidekiq_cmd)} #{args.compact.join(' ')} ; else echo 'Sidekiq is already running'; fi"
|
101
|
-
end
|
102
|
-
|
103
|
-
desc 'Quiet sidekiq (stop accepting new work)'
|
104
|
-
task :quiet, roles: lambda { fetch(:sidekiq_role) }, on_no_matching_servers: :continue do
|
105
|
-
for_each_role do |sidekiq_role|
|
106
|
-
for_each_process(sidekiq_role) do |pid_file, idx|
|
107
|
-
quiet_process(pid_file, idx, sidekiq_role)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
desc 'Stop sidekiq'
|
113
|
-
task :stop, roles: lambda { fetch(:sidekiq_role) }, on_no_matching_servers: :continue do
|
114
|
-
for_each_role do |sidekiq_role|
|
115
|
-
for_each_process(sidekiq_role) do |pid_file, idx|
|
116
|
-
stop_process(pid_file, idx, sidekiq_role)
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
desc 'Start sidekiq'
|
122
|
-
task :start, roles: lambda { fetch(:sidekiq_role) }, on_no_matching_servers: :continue do
|
123
|
-
for_each_role do |sidekiq_role|
|
124
|
-
for_each_process(sidekiq_role) do |pid_file, idx|
|
125
|
-
start_process(pid_file, idx, sidekiq_role)
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
desc 'Rolling-restart sidekiq'
|
131
|
-
task :rolling_restart, roles: lambda { fetch(:sidekiq_role) }, on_no_matching_servers: :continue do
|
132
|
-
for_each_role do |sidekiq_role|
|
133
|
-
for_each_process(sidekiq_role) do |pid_file, idx|
|
134
|
-
stop_process(pid_file, idx, sidekiq_role)
|
135
|
-
start_process(pid_file, idx, sidekiq_role)
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
desc 'Restart sidekiq'
|
141
|
-
task :restart, roles: lambda { fetch(:sidekiq_role) }, on_no_matching_servers: :continue do
|
142
|
-
stop
|
143
|
-
start
|
144
|
-
end
|
145
|
-
|
146
|
-
end
|
147
|
-
end
|