capistrano-sidekiq 0.20.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,296 @@
1
+ # frozen_string_literal: true
2
+
3
+ git_plugin = self
4
+
5
+ namespace :sidekiq do
6
+ standard_actions = {
7
+ start: 'Start Sidekiq',
8
+ stop: 'Stop Sidekiq (graceful shutdown within timeout, put unfinished tasks back to Redis)',
9
+ status: 'Get Sidekiq Status'
10
+ }
11
+ standard_actions.each do |command, description|
12
+ desc description
13
+ task command do
14
+ on roles fetch(:sidekiq_roles) do |role|
15
+ git_plugin.switch_user(role) do
16
+ git_plugin.systemctl_command(command)
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ desc 'Restart Sidekiq (Quiet, Wait till workers finish or 30 seconds, Stop, Start)'
23
+ task :restart do
24
+ on roles fetch(:sidekiq_roles) do |role|
25
+ git_plugin.switch_user(role) do
26
+ git_plugin.quiet_sidekiq
27
+ git_plugin.process_block do |process|
28
+ start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
29
+ running = nil
30
+
31
+ # get running workers
32
+ while (running.nil? || running > 0) && git_plugin.duration(start_time) < 30 do
33
+ command_args =
34
+ if fetch(:sidekiq_service_unit_user) == :system
35
+ [:sudo, 'systemd-cgls']
36
+ else
37
+ ['systemd-cgls', '--user']
38
+ end
39
+ # need to pipe through tr -cd... to strip out systemd colors or you
40
+ # get log error messages for non UTF-8 characters.
41
+ command_args.push(
42
+ '-u', "#{git_plugin.sidekiq_service_unit_name(process: process)}.service",
43
+ '|', 'tr -cd \'\11\12\15\40-\176\''
44
+ )
45
+ status = capture(*command_args, raise_on_non_zero_exit: false)
46
+ status_match = status.match(/\[(?<running>\d+) of (?<total>\d+) busy\]/)
47
+ break unless status_match
48
+
49
+ running = status_match[:running]&.to_i
50
+
51
+ colors = SSHKit::Color.new($stdout)
52
+ if running.zero?
53
+ info colors.colorize("✔ Process ##{process}: No running workers. Shutting down for restart!", :green)
54
+ else
55
+ info colors.colorize("⧗ Process ##{process}: Waiting for #{running} workers.", :yellow)
56
+ sleep(1)
57
+ end
58
+ end
59
+
60
+ git_plugin.systemctl_command(:stop, process: process)
61
+ git_plugin.systemctl_command(:start, process: process)
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ desc 'Quiet Sidekiq (stop fetching new tasks from Redis)'
68
+ task :quiet do
69
+ on roles fetch(:sidekiq_roles) do |role|
70
+ git_plugin.switch_user(role) do
71
+ git_plugin.quiet_sidekiq
72
+ end
73
+ end
74
+ end
75
+
76
+ desc 'Install systemd sidekiq service'
77
+ task :install do
78
+ on roles fetch(:sidekiq_roles) do |role|
79
+ git_plugin.switch_user(role) do
80
+ git_plugin.create_systemd_template
81
+ if git_plugin.config_per_process?
82
+ git_plugin.process_block do |process|
83
+ git_plugin.create_systemd_config_symlink(process)
84
+ end
85
+ end
86
+ git_plugin.systemctl_command(:enable)
87
+
88
+ if fetch(:sidekiq_service_unit_user) != :system && fetch(:sidekiq_enable_lingering)
89
+ execute :loginctl, 'enable-linger', fetch(:sidekiq_lingering_user)
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ desc 'Uninstall systemd sidekiq service'
96
+ task :uninstall do
97
+ on roles fetch(:sidekiq_roles) do |role|
98
+ git_plugin.switch_user(role) do
99
+ git_plugin.systemctl_command(:stop)
100
+ git_plugin.systemctl_command(:disable)
101
+ if git_plugin.config_per_process?
102
+ git_plugin.process_block do |process|
103
+ git_plugin.delete_systemd_config_symlink(process)
104
+ end
105
+ end
106
+ execute :sudo, :rm, '-f', File.join(
107
+ fetch(:service_unit_path, git_plugin.fetch_systemd_unit_path),
108
+ git_plugin.sidekiq_service_file_name
109
+ )
110
+ end
111
+ end
112
+ end
113
+
114
+ desc 'Generate service_locally'
115
+ task :generate_service_locally do
116
+ run_locally do
117
+ File.write('sidekiq', git_plugin.compiled_template)
118
+ end
119
+ end
120
+
121
+ def fetch_systemd_unit_path
122
+ if fetch(:sidekiq_service_unit_user) == :system
123
+ # if the path is not standard `set :service_unit_path`
124
+ '/etc/systemd/system/'
125
+ else
126
+ home_dir = backend.capture :pwd
127
+ File.join(home_dir, '.config', 'systemd', 'user')
128
+ end
129
+ end
130
+
131
+ def compiled_template
132
+ local_template_directory = fetch(:sidekiq_service_templates_path)
133
+ search_paths = [
134
+ File.join(local_template_directory, "#{fetch(:sidekiq_service_unit_name)}.service.capistrano.erb"),
135
+ File.join(local_template_directory, 'sidekiq.service.capistrano.erb'),
136
+ File.expand_path(
137
+ File.join(*%w[.. .. .. generators capistrano sidekiq systemd templates sidekiq.service.capistrano.erb]),
138
+ __FILE__
139
+ )
140
+ ]
141
+ template_path = search_paths.detect { |path| File.file?(path) }
142
+ template = File.read(template_path)
143
+ ERB.new(template).result(binding)
144
+ end
145
+
146
+ def create_systemd_template
147
+ ctemplate = compiled_template
148
+ systemd_path = fetch(:service_unit_path, fetch_systemd_unit_path)
149
+ backend.execute :mkdir, '-p', systemd_path if fetch(:sidekiq_service_unit_user) == :user
150
+
151
+ if sidekiq_processes > 1
152
+ range = 1..sidekiq_processes
153
+ else
154
+ range = 0..0
155
+ end
156
+ range.each do |index|
157
+ temp_file_name = File.join('/tmp', sidekiq_service_file_name(index))
158
+ systemd_file_name = File.join(systemd_path, sidekiq_service_file_name(index))
159
+ backend.upload!(StringIO.new(ctemplate), temp_file_name)
160
+
161
+ if fetch(:sidekiq_service_unit_user) == :system
162
+ backend.execute :sudo, :mv, temp_file_name, systemd_file_name
163
+ backend.execute :sudo, :systemctl, 'daemon-reload'
164
+ else
165
+ backend.execute :mv, temp_file_name, systemd_file_name
166
+ backend.execute :systemctl, '--user', 'daemon-reload'
167
+ end
168
+ end
169
+ end
170
+
171
+ def create_systemd_config_symlink(process)
172
+ config = fetch(:sidekiq_config)
173
+ return unless config
174
+
175
+ process_config = config[process - 1]
176
+ if process_config.nil?
177
+ backend.error(
178
+ "No configuration for Process ##{process} found. "\
179
+ 'Please make sure you have 1 item in :sidekiq_config for each process.'
180
+ )
181
+ exit 1
182
+ end
183
+
184
+ base_path = fetch(:deploy_to)
185
+ config_link_base_path = File.join(base_path, 'shared', 'sidekiq_systemd')
186
+ config_link_path = File.join(
187
+ config_link_base_path, sidekiq_systemd_config_name(process)
188
+ )
189
+ process_config_path = File.join(base_path, 'current', process_config)
190
+
191
+ backend.execute :mkdir, '-p', config_link_base_path
192
+ backend.execute :ln, '-sf', process_config_path, config_link_path
193
+ end
194
+
195
+ def delete_systemd_config_symlink(process)
196
+ config_link_path = File.join(
197
+ fetch(:deploy_to), 'shared', 'sidekiq_systemd',
198
+ sidekiq_systemd_config_name(process)
199
+ )
200
+ backend.execute :rm, config_link_path, raise_on_non_zero_exit: false
201
+ end
202
+
203
+ def systemctl_command(*args, process: nil)
204
+ execute_array =
205
+ if fetch(:sidekiq_service_unit_user) == :system
206
+ %i[sudo systemctl]
207
+ else
208
+ [:systemctl, '--user']
209
+ end
210
+ if process && sidekiq_processes > 1
211
+ execute_array.push(
212
+ *args, sidekiq_service_unit_name(process: process)
213
+ ).flatten
214
+ else
215
+ execute_array.push(*args, sidekiq_service_unit_name).flatten
216
+ end
217
+ backend.execute(*execute_array, raise_on_non_zero_exit: false)
218
+ end
219
+
220
+ def quiet_sidekiq
221
+ systemctl_command(:kill, '-s', :TSTP)
222
+ end
223
+
224
+ def switch_user(role, &block)
225
+ su_user = sidekiq_user
226
+ if su_user != role.user
227
+ yield
228
+ else
229
+ backend.as su_user, &block
230
+ end
231
+ end
232
+
233
+ def sidekiq_user
234
+ fetch(:sidekiq_user, fetch(:run_as))
235
+ end
236
+
237
+ def sidekiq_config
238
+ config = fetch(:sidekiq_config)
239
+ return unless config
240
+
241
+ if config_per_process?
242
+ config = File.join(
243
+ fetch(:deploy_to), 'shared', 'sidekiq_systemd',
244
+ sidekiq_systemd_config_name
245
+ )
246
+ end
247
+ "--config #{config}"
248
+ end
249
+
250
+ def sidekiq_concurrency
251
+ "--concurrency #{fetch(:sidekiq_concurrency)}" if fetch(:sidekiq_concurrency)
252
+ end
253
+
254
+ def sidekiq_processes
255
+ fetch(:sidekiq_processes, 1)
256
+ end
257
+
258
+ def sidekiq_queues
259
+ Array(fetch(:sidekiq_queue)).map do |queue|
260
+ "--queue #{queue}"
261
+ end.join(' ')
262
+ end
263
+
264
+ def sidekiq_service_file_name(index = nil)
265
+ return "#{fetch(:sidekiq_service_unit_name)}.service" if index.to_i.zero?
266
+ "#{fetch(:sidekiq_service_unit_name)}@#{index}.service"
267
+ end
268
+
269
+ def sidekiq_service_unit_name(process: nil)
270
+ if process && sidekiq_processes > 1
271
+ "#{fetch(:sidekiq_service_unit_name)}@#{process}"
272
+ else
273
+ fetch(:sidekiq_service_unit_name)
274
+ end
275
+ end
276
+
277
+ # process = 1 | sidekiq_systemd_1.yaml
278
+ # process = nil | sidekiq_systemd_%i.yaml
279
+ def sidekiq_systemd_config_name(process = nil)
280
+ "sidekiq_systemd_#{(process&.to_s || '%i')}.yaml"
281
+ end
282
+
283
+ def config_per_process?
284
+ fetch(:sidekiq_config).is_a?(Array)
285
+ end
286
+
287
+ def process_block
288
+ (1..sidekiq_processes).each do |process|
289
+ yield(process)
290
+ end
291
+ end
292
+
293
+ def duration(start_time)
294
+ Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time
295
+ end
296
+ end
@@ -1,10 +1,8 @@
1
- # Monit configuration for Sidekiq : <%= fetch(:application) %>
2
- <% processes_pids.each_with_index do |pid_file, idx| %>
3
- check process <%= sidekiq_service_name(idx) %>
4
- with pidfile "<%= pid_file %>"
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
6
-
7
- stop program = "/bin/su - <%= sidekiq_user(@role) %> -c 'cd <%= current_path %> && <%= SSHKit.config.command_map[:sidekiqctl] %> stop <%= pid_file %>'" with timeout <%= fetch(:sidekiq_timeout).to_i + 10 %> seconds
8
- group <%= fetch(:sidekiq_monit_group, fetch(:application)) %>-sidekiq
9
-
10
- <% end %>
1
+ # Monit configuration for Sidekiq
2
+ # Service name: <%= sidekiq_service_name %>
3
+ #
4
+ check process <%= sidekiq_service_name %>
5
+ matching 'sidekiq .* <%= fetch(:application) %>'
6
+ start program = "/bin/su - <%= sidekiq_user(role) %> -c 'cd <%= current_path %> && <%= SSHKit.config.command_map[:bundle] %> exec sidekiq -e <%= fetch(:sidekiq_env) %> <%= sidekiq_config %> <%= sidekiq_concurrency %> <%= sidekiq_require %> <%= sidekiq_queues %> <%= sidekiq_logfile ? ">> #{sidekiq_logfile} 2>&1" : nil %> &'" with timeout <%= fetch(:sidekiq_timeout).to_i + 10 %> seconds
7
+ stop program = "/bin/su - <%= sidekiq_user(role) %> -c 'ps ax | grep "<%= "sidekiq .* #{fetch(:application)}" %>" | grep -v grep | awk "{print \$1}" | xargs --no-run-if-empty kill'" with timeout <%= fetch(:sidekiq_timeout).to_i + 10 %> seconds
8
+ group <%= fetch(:sidekiq_monit_group) || fetch(:application) %>-sidekiq
@@ -0,0 +1,68 @@
1
+ # Source: https://github.com/mperham/sidekiq/blob/master/examples/systemd/sidekiq.service
2
+ #
3
+ # This file tells systemd how to run Sidekiq as a 24/7 long-running daemon.
4
+ #
5
+ # Customize this file based on your bundler location, app directory, etc.
6
+ # Customize and copy this into /usr/lib/systemd/system (CentOS) or /lib/systemd/system (Ubuntu).
7
+ # Then run:
8
+ # - systemctl enable <%= sidekiq_service_unit_name %>
9
+ # - systemctl {start,stop,restart} <%= sidekiq_service_unit_name %>
10
+ #
11
+ # This file corresponds to a single Sidekiq process. Add multiple copies
12
+ # to run multiple processes (sidekiq-1, sidekiq-2, etc).
13
+ #
14
+ # Use `journalctl -u <%= sidekiq_service_unit_name %> -rn 100` to view the last 100 lines of log output.
15
+ #
16
+ [Unit]
17
+ Description=sidekiq for <%= "#{fetch(:application)} (#{fetch(:stage)})" %>
18
+ # start us only once the network and logging subsystems are available,
19
+ # consider adding redis-server.service if Redis is local and systemd-managed.
20
+ After=syslog.target network.target
21
+
22
+ # See these pages for lots of options:
23
+ #
24
+ # https://www.freedesktop.org/software/systemd/man/systemd.service.html
25
+ # https://www.freedesktop.org/software/systemd/man/systemd.exec.html
26
+ #
27
+ # THOSE PAGES ARE CRITICAL FOR ANY LINUX DEVOPS WORK; read them multiple
28
+ # times! systemd is a critical tool for all developers to know and understand.
29
+ #
30
+ [Service]
31
+ #
32
+ # !!!! !!!! !!!!
33
+ #
34
+ # As of v6.0.6, Sidekiq automatically supports systemd's `Type=notify` and watchdog service
35
+ # monitoring. If you are using an earlier version of Sidekiq, change this to `Type=simple`
36
+ # and remove the `WatchdogSec` line.
37
+ #
38
+ # !!!! !!!! !!!!
39
+ #
40
+ Type=notify
41
+ # If your Sidekiq process locks up, systemd's watchdog will restart it within seconds.
42
+ WatchdogSec=10
43
+
44
+ WorkingDirectory=<%= File.join(fetch(:deploy_to), 'current') %>
45
+ ExecStart=<%= expanded_bundle_path %> exec sidekiq -e <%= fetch(:sidekiq_env) %> <%= sidekiq_config %> <%= sidekiq_concurrency %> <%= sidekiq_queues %>
46
+
47
+ # Use `systemctl kill -s TSTP <%= sidekiq_service_unit_name %>` to quiet the Sidekiq process
48
+ <%="User=#{sidekiq_user}" if sidekiq_user %>
49
+ UMask=0002
50
+
51
+ <%="EnvironmentFile=#{File.join(fetch(:deploy_to), 'current')}/#{fetch(:sidekiq_service_unit_env_file)}" if fetch(:sidekiq_service_unit_env_file) %>
52
+
53
+ <% fetch(:sidekiq_service_unit_env_vars, []).each do |environment_variable| %>
54
+ <%="Environment=#{environment_variable}" %>
55
+ <% end %>
56
+
57
+ # if we crash, restart
58
+ RestartSec=1
59
+ Restart=on-failure
60
+
61
+ # output goes to /var/log/syslog (Ubuntu) or /var/log/messages (CentOS)
62
+ <%="StandardOutput=append:#{fetch(:sidekiq_log)}" if fetch(:sidekiq_log) %>
63
+ <%="StandardError=append:#{fetch(:sidekiq_error_log)}" if fetch(:sidekiq_error_log) %>
64
+
65
+ SyslogIdentifier=<%= sidekiq_service_unit_name %>
66
+
67
+ [Install]
68
+ WantedBy=default.target
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.20.0
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Abdelkader Boudih
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-01 00:00:00.000000000 Z
11
+ date: 2022-05-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: capistrano
@@ -24,20 +24,34 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 3.9.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: capistrano-bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: sidekiq
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - ">="
32
46
  - !ruby/object:Gem::Version
33
- version: '3.4'
47
+ version: '6.0'
34
48
  type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - ">="
39
53
  - !ruby/object:Gem::Version
40
- version: '3.4'
54
+ version: '6.0'
41
55
  description: Sidekiq integration for Capistrano
42
56
  email:
43
57
  - terminale@gmail.com
@@ -46,8 +60,8 @@ extensions: []
46
60
  extra_rdoc_files: []
47
61
  files:
48
62
  - ".gitignore"
49
- - CHANGELOG
50
- - CONTRIBUTORS.md
63
+ - ".tool-versions"
64
+ - CHANGELOG.md
51
65
  - Gemfile
52
66
  - LICENSE.txt
53
67
  - README.md
@@ -55,18 +69,21 @@ files:
55
69
  - capistrano-sidekiq.gemspec
56
70
  - lib/capistrano-sidekiq.rb
57
71
  - lib/capistrano/sidekiq.rb
72
+ - lib/capistrano/sidekiq/helpers.rb
58
73
  - lib/capistrano/sidekiq/monit.rb
74
+ - lib/capistrano/sidekiq/systemd.rb
59
75
  - lib/capistrano/sidekiq/version.rb
60
- - lib/capistrano/tasks/capistrano2.rb
61
76
  - lib/capistrano/tasks/monit.rake
62
77
  - lib/capistrano/tasks/sidekiq.rake
78
+ - lib/capistrano/tasks/systemd.rake
63
79
  - lib/generators/capistrano/sidekiq/monit/template_generator.rb
64
80
  - lib/generators/capistrano/sidekiq/monit/templates/sidekiq_monit.conf.erb
81
+ - lib/generators/capistrano/sidekiq/systemd/templates/sidekiq.service.capistrano.erb
65
82
  homepage: https://github.com/seuros/capistrano-sidekiq
66
83
  licenses:
67
84
  - LGPL-3.0
68
85
  metadata: {}
69
- post_install_message:
86
+ post_install_message:
70
87
  rdoc_options: []
71
88
  require_paths:
72
89
  - lib
@@ -81,9 +98,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
98
  - !ruby/object:Gem::Version
82
99
  version: '0'
83
100
  requirements: []
84
- rubyforge_project:
85
- rubygems_version: 2.6.11
86
- signing_key:
101
+ rubygems_version: 3.2.22
102
+ signing_key:
87
103
  specification_version: 4
88
104
  summary: Sidekiq integration for Capistrano
89
105
  test_files: []
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
data/CONTRIBUTORS.md DELETED
@@ -1,11 +0,0 @@
1
- ## Contributors
2
-
3
- - [Jérémy Lecour] (https://github.com/jlecour)
4
- - [Fabien Penso] (https://github.com/penso)
5
- - [Alex Dunae] (https://github.com/alexdunae)
6
- - [andreygerasimchuk] (https://github.com/andreygerasimchuk)
7
- - [Saicheg] (https://github.com/Saicheg)
8
- - [Alex Yakubenko] (https://github.com/alexyakubenko)
9
- - [Robert Strobl] (https://github.com/rstrobl)
10
- - [Eurico Doirado] (https://github.com/okoriko)
11
- - [Huang Bin](https://github.com/hbin)
@@ -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