capistrano-sidekiq 0.20.0 → 2.3.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.
@@ -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