sidekiq-redeploy 0.1.8 → 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 622ce6da0eb4f0f2507ff8b5ba81cb24909118469e552d856139e25b0b5bb328
4
- data.tar.gz: c968b066fa65f1c4ab70345af149774cd8a2483abc0970103a3c50eb99893b47
3
+ metadata.gz: de3104469105eed517e7e6994858454b80e102d10a7dc793b1517552ff7d6a53
4
+ data.tar.gz: c5264950908153ce688ba6700270163a1ac21a7e91fc88d1e8443a5098704b88
5
5
  SHA512:
6
- metadata.gz: dd933b670a81709895c6e2fe057421f8aa354297b54b303d7364aaaf618f1f7673074769d561794b6f9e24bde1a765e081940e14c9cc8f88488c57b5ce04169d
7
- data.tar.gz: 80aa2eac63fe6baca128a5eb0eab93c3833e2df0f529ec6b9078eedd8e23277484d4bd51dcb5fa25e79e73077cd5066e714b3249908a8da2fdef1cfea3e45f79
6
+ metadata.gz: a6f6ade2223e07932aef74b35ea262cd19635dabb34cf8ab4ad27dc3cf8e49b59184d7196bd087636d4ecb758496a2aaccbcdf85f11700185c1be09e5f6a8fe1
7
+ data.tar.gz: 05b1f9e28ae95f7e532367a7bf79a314487bc40fd1b70576ae552ce7e5240235cb7fa541a7bc940d8b412e849eeeab7085d261b365b74144dc10617f08a995a6
data/.rubocop.yml CHANGED
@@ -19,7 +19,10 @@ Metrics/MethodLength:
19
19
  Max: 30
20
20
 
21
21
  Metrics/ClassLength:
22
- Max: 120
22
+ Max: 140
23
+
24
+ Metrics/AbcSize:
25
+ Max: 30
23
26
 
24
27
  RSpec/NestedGroups:
25
28
  Max: 4
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## v0.1.10
2
+
3
+ **Fixes and enhancements:**
4
+
5
+ - Add support to run commands prior to redeploy using a yaml watch file. This is useful for running a migration or bundle gems.
6
+
7
+ ## v0.1.9
8
+
9
+ **Fixes and enhancements:**
10
+
11
+ - Allow users to specify number of sidekiq worker processes with -n flag
12
+
1
13
  ## v0.1.8
2
14
 
3
15
  **Fixes and enhancements:**
data/README.md CHANGED
@@ -40,11 +40,34 @@ Usage: sidekiq-loader [options]
40
40
  -y, --watch-delay INTEGER [Optional] Specify the number of seconds between checking watch file. Defaults to 30.
41
41
  -d, --[no-]deploy [FLAG] [Optional] Deploy archive on app startup. Defaults to true.
42
42
  -s, --sidekiq-app [PATH|DIR] [Optional] Location of application to pass to sidekiq.
43
+ -n, --num-procs INTEGER [Optional] Specify the number of sidekiq processes to create. Defaults to 1.
43
44
  ```
44
45
 
45
- For example this will start the launcher using a S3 watch file.
46
+ The watch file can contain an optional list of commands to run and the required archive_location. The archive_location can be a file path or S3 URL
47
+ For example when using a file:
48
+ ```yaml
49
+ ---
50
+ commands:
51
+ - bundle
52
+ archive_location: /app/pkg/test_app_0.0.3.zip
53
+ ```
54
+
55
+ For example when using S3:
56
+ ```yaml
57
+ ---
58
+ commands:
59
+ - bundle
60
+ archive_location: s3://puma-test-app-archives/test_app_0.0.3.zip
61
+ ```
62
+
63
+ For example this will start the launcher using a S3 yaml watch file.
64
+ ```shell
65
+ bundle exec sidekiq-loader -a /app -w s3://puma-test-app-archives/watch.yml
66
+ ```
67
+
68
+ For example this will start the launcher using a local yaml watch file.
46
69
  ```shell
47
- bundle exec sidekiq-loader -a /app -w s3://puma-test-app-archives/watch.me
70
+ bundle exec sidekiq-loader -a ./ -s ./lib/sidekiq_server.rb -w build/pkg/watch.yml
48
71
  ```
49
72
 
50
73
  In the example above the `watch.me` contents would look like the following. In this case the `test_app_0.0.3.zip` must exist in the `puma-test-app-archives` S3 bucket.
data/bin/sidekiq-loader CHANGED
@@ -9,11 +9,16 @@ require 'optparse'
9
9
  def run_sidekiq(ops, logger)
10
10
  deployer = Puma::Redeploy::DeployerFactory.create(target: ops[:app_dir], watch_file: ops[:watch], logger:)
11
11
 
12
+ watch_file_data = deployer.watch_file_data
13
+
14
+ archive_file = deployer.archive_file(watch_file_data[:archive_location])
15
+
12
16
  # Load app archive on launch
13
- deployer.deploy(source: deployer.archive_file) if ops[:deploy]
17
+ deployer.deploy(source: archive_file) if ops[:deploy]
14
18
  config = { watch_delay: ops[:watch_delay] }
15
19
 
16
- Sidekiq::Redeploy::Loader.new(deployer:, logger:, sidekiq_app: ops[:sidekiq_app], config:).run
20
+ Sidekiq::Redeploy::Loader.new(deployer:, logger:, sidekiq_app: ops[:sidekiq_app], config:,
21
+ num_processes: ops[:num_processes]).run
17
22
  end
18
23
 
19
24
  def option_parser(opts)
@@ -39,6 +44,11 @@ def option_parser(opts)
39
44
  o.on '-s', '--sidekiq-app [PATH|DIR]', '[Optional] Location of application to pass to sidekiq.' do |arg|
40
45
  opts[:sidekiq_app] = arg
41
46
  end
47
+
48
+ o.on '-n', '--num-procs INTEGER', Integer,
49
+ '[Optional] Specify the number of sidekiq processes to create. Defaults to 1.' do |arg|
50
+ opts[:num_processes] = arg
51
+ end
42
52
  end
43
53
  end
44
54
 
@@ -15,9 +15,8 @@ module Sidekiq
15
15
 
16
16
  SIGNALS = [INT, TERM, USR2, TTIN].freeze
17
17
 
18
- def initialize(deployer:, sidekiq_app: nil, logger: Logger.new($stdout), config: {})
18
+ def initialize(deployer:, sidekiq_app: nil, logger: Logger.new($stdout), config: {}, num_processes: 1)
19
19
  require 'sidekiq/cli'
20
-
21
20
  @reload_sidekiq = false
22
21
  @exit_loader = false
23
22
  @loader_pid = ::Process.pid
@@ -28,6 +27,8 @@ module Sidekiq
28
27
  @loop_delay = config[:loop_delay] || 0.5
29
28
  @deployer = deployer
30
29
  @sidekiq_app = sidekiq_app
30
+ @num_processes = num_processes || 1
31
+ @sidekiq_pids = []
31
32
  end
32
33
 
33
34
  def run
@@ -46,7 +47,7 @@ module Sidekiq
46
47
  rescue StandardError => e
47
48
  log "Error in sidekiq loader: #{e.message}"
48
49
  log e.backtrace.join("\n")
49
- stop_sidekiq(@sidekiq_pid)
50
+ stop_sidekiq(@sidekiq_pids)
50
51
  ::Process.waitall
51
52
  exit 1
52
53
  end
@@ -59,15 +60,25 @@ module Sidekiq
59
60
  loop do
60
61
  sleep(loop_delay)
61
62
  if needs_redeploy?
62
- reload_app { deployer.deploy(source: deployer.archive_file) }
63
+ reload_app do
64
+ watch_file_data = deployer.watch_file_data
65
+
66
+ archive_file = deployer.archive_file(watch_file_data[:archive_location])
67
+
68
+ logger.info "Sidekiq restart begin file=#{deployer.watch_file} archive=#{archive_file}"
69
+
70
+ Puma::Redeploy::CommandRunner.new(commands: watch_file_data[:commands], logger:).run
71
+
72
+ deployer.deploy(source: archive_file)
73
+ end
63
74
  elsif reload_sidekiq
64
75
  reload_app
65
- elsif process_died?(@sidekiq_pid)
66
- fork_sidekiq
67
76
  end
77
+ @sidekiq_pids = running_pids(@sidekiq_pids)
78
+ fork_sidekiq(@num_processes - @sidekiq_pids.length) if @sidekiq_pids.length < @num_processes
68
79
  next unless exit_loader
69
80
 
70
- stop_sidekiq(@sidekiq_pid)
81
+ stop_sidekiq(@sidekiq_pids)
71
82
  break
72
83
  end
73
84
  end
@@ -80,30 +91,32 @@ module Sidekiq
80
91
  end
81
92
 
82
93
  def reload_app
83
- quiet_sidekiq(@sidekiq_pid)
94
+ quiet_sidekiq(@sidekiq_pids)
84
95
 
85
96
  yield if block_given?
86
97
 
87
- stop_sidekiq(@sidekiq_pid)
98
+ stop_sidekiq(@sidekiq_pids)
88
99
 
89
100
  # wait for sidekiq to stop
90
101
  ::Process.waitall
91
-
92
102
  fork_sidekiq
93
103
  @reload_sidekiq = false
94
104
  end
95
105
 
96
- def fork_sidekiq
97
- @sidekiq_pid = ::Process.fork do
98
- cli = Sidekiq::CLI.instance
99
- args = @sidekiq_app ? ['-r', @sidekiq_app] : []
100
- cli.parse(args)
101
- cli.run
102
- rescue StandardError => e
103
- message = "Error loading sidekiq process: #{e.message}"
104
- log message
105
- log e.backtrace.join("\n")
106
- raise message
106
+ def fork_sidekiq(num_children = @num_processes)
107
+ num_children.times do
108
+ pid = ::Process.fork do
109
+ cli = Sidekiq::CLI.instance
110
+ args = @sidekiq_app ? ['-r', @sidekiq_app] : []
111
+ cli.parse(args)
112
+ cli.run
113
+ rescue StandardError => e
114
+ message = "Error loading sidekiq process: #{e.message}"
115
+ log message
116
+ log e.backtrace.join("\n")
117
+ raise message
118
+ end
119
+ @sidekiq_pids << pid
107
120
  end
108
121
  end
109
122
 
@@ -126,32 +139,41 @@ module Sidekiq
126
139
  when USR2
127
140
  @reload_sidekiq = true
128
141
  when TTIN
129
- ::Process.kill(signal, @sidekiq_pid)
142
+ @sidekiq_pids.each do |pid|
143
+ ::Process.kill(signal, pid)
144
+ end
130
145
  when TERM, INT
131
146
  @exit_loader = true
132
147
  end
133
148
  end
134
149
 
135
150
  def debug_handler(signal)
136
- log_data = { signal:, current_pid: ::Process.pid, loader_pid: @loader_pid, sidekiq_pid: @sidekiq_pid,
151
+ log_data = { signal:, current_pid: ::Process.pid, loader_pid: @loader_pid, sidekiq_pids: @sidekiq_pids,
137
152
  reload_sidekiq: @reload_sidekiq, exit_loader: @exit_loader }
138
153
  puts "handle_signal called with #{log_data}"
139
154
  end
140
155
 
141
- def stop_sidekiq(pid)
142
- ::Process.kill(TERM, pid) if pid
156
+ def stop_sidekiq(pids)
157
+ pids.each do |pid|
158
+ ::Process.kill(TERM, pid)
159
+ end
160
+ @sidekiq_pids = []
143
161
  end
144
162
 
145
- def quiet_sidekiq(pid)
146
- ::Process.kill(TSTP, pid) if pid
163
+ def quiet_sidekiq(pids)
164
+ pids.each do |pid|
165
+ ::Process.kill(TSTP, pid)
166
+ end
147
167
  end
148
168
 
149
- def process_died?(pid)
150
- return false if @exit_loader
151
-
152
- !::Process.getpgid(pid)
153
- rescue StandardError
154
- true
169
+ def running_pids(pids)
170
+ new_pids = []
171
+ pids.each do |pid|
172
+ new_pids << pid unless ::Process.waitpid(pid, ::Process::WNOHANG)
173
+ rescue Errno::ECHILD
174
+ log "PID #{pid} does not exist."
175
+ end
176
+ new_pids
155
177
  end
156
178
 
157
179
  def log(message)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sidekiq
4
4
  module Redeploy
5
- VERSION = '0.1.8'
5
+ VERSION = '0.1.10'
6
6
  end
7
7
  end
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.bindir = 'bin'
33
33
  spec.require_paths = ['lib']
34
34
 
35
- spec.add_dependency 'puma-redeploy', '~> 0.3.3'
35
+ spec.add_dependency 'puma-redeploy', '~> 0.3.4'
36
36
  spec.add_dependency 'sidekiq', '>= 6', '< 8'
37
37
 
38
38
  spec.metadata['rubygems_mfa_required'] = 'true'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq-redeploy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - tbeauvais
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-22 00:00:00.000000000 Z
11
+ date: 2024-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: puma-redeploy
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.3.3
19
+ version: 0.3.4
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.3.3
26
+ version: 0.3.4
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sidekiq
29
29
  requirement: !ruby/object:Gem::Requirement