sidekiq-redeploy 0.1.8 → 0.1.10

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 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