sidekiq-runner 0.1.1 → 0.2.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 +5 -5
- data/lib/sidekiq-runner.rb +23 -7
- data/lib/sidekiq-runner/god_configuration.rb +25 -4
- data/lib/sidekiq-runner/sidekiq.god +27 -4
- data/lib/sidekiq-runner/sidekiq_configuration.rb +1 -5
- data/lib/sidekiq-runner/sidekiq_instance.rb +21 -24
- data/lib/sidekiq-runner/version.rb +1 -1
- data/script/sidekiq_rbtrace +32 -0
- metadata +20 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c8918e2e7486207c0a59ae645ec003d7ce1de255ba8e60e48ae9265e3db829b9
|
4
|
+
data.tar.gz: 7931bf1755ef7b945443ea9a6b9c73199e88b3ad5d05e0975baf9b4cd7798480
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf8d8f5617fa3eea88088bc14202ccb52a252e4c2e2ba9b7c53c455a9b6929e2218668e5a1b1790c2af42246dae8572b942a65ea645b242a8b53fede15fbad99
|
7
|
+
data.tar.gz: 861b4a172a2c35d738e12b178b9550b9df09d927cf1772a1a3866fc6564ba162d3aad5cb3337a5e21742e86ad417b6d97df2c5991c015031a1db8c41e7622204
|
data/lib/sidekiq-runner.rb
CHANGED
@@ -17,7 +17,7 @@ module SidekiqRunner
|
|
17
17
|
|
18
18
|
abort 'God is already running.' if god_alive?(god_config)
|
19
19
|
|
20
|
-
run(:start, sidekiq_config) do
|
20
|
+
run(:start, sidekiq_config, god_config) do
|
21
21
|
$0 = "SidekiqRunner/God (#{god_config.process_name})"
|
22
22
|
|
23
23
|
puts 'Starting god.'
|
@@ -31,7 +31,7 @@ module SidekiqRunner
|
|
31
31
|
def self.stop
|
32
32
|
sidekiq_config, god_config = SidekiqConfiguration.get, GodConfiguration.get
|
33
33
|
|
34
|
-
run(:stop, sidekiq_config) do
|
34
|
+
run(:stop, sidekiq_config, god_config) do
|
35
35
|
God::EventHandler.load
|
36
36
|
|
37
37
|
if god_alive?(god_config)
|
@@ -48,6 +48,17 @@ module SidekiqRunner
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
+
def self.restart(sidekiq_instances: [])
|
52
|
+
sidekiq_config = SidekiqConfiguration.get
|
53
|
+
god_config = GodConfiguration.get
|
54
|
+
|
55
|
+
return unless god_alive?(god_config)
|
56
|
+
|
57
|
+
sidekiq_config.each_key do |name|
|
58
|
+
God::CLI::Command.new('restart', god_config.options, ['', name]) if sidekiq_instances.empty? || sidekiq_instances.include?(name.to_sym)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
51
62
|
def self.running?
|
52
63
|
god_alive? GodConfiguration.get
|
53
64
|
end
|
@@ -69,7 +80,7 @@ module SidekiqRunner
|
|
69
80
|
true
|
70
81
|
end
|
71
82
|
|
72
|
-
def self.run(action, sidekiq_config)
|
83
|
+
def self.run(action, sidekiq_config, god_config)
|
73
84
|
begin
|
74
85
|
|
75
86
|
# Use this flag to actually load all of the god infrastructure.
|
@@ -77,16 +88,21 @@ module SidekiqRunner
|
|
77
88
|
require 'god'
|
78
89
|
require 'god/cli/run'
|
79
90
|
|
91
|
+
if [:start, :stop].include? action
|
92
|
+
cb = god_config.send("before_#{action}_cb".to_sym)
|
93
|
+
cb.call if cb
|
94
|
+
end
|
95
|
+
|
80
96
|
# Peform the action.
|
81
97
|
yield if block_given?
|
82
98
|
|
83
99
|
rescue SystemExit => e
|
84
|
-
|
100
|
+
sidekiq_cb = e.success? ? "#{action}_success_cb" : "#{action}_error_cb"
|
85
101
|
ensure
|
86
102
|
if [:start, :stop].include? action
|
87
|
-
|
88
|
-
|
89
|
-
|
103
|
+
sidekiq_cb = "#{action}_success_cb" unless sidekiq_cb
|
104
|
+
sidekiq_cb = sidekiq_config.send(sidekiq_cb.to_sym)
|
105
|
+
sidekiq_cb.call if sidekiq_cb
|
90
106
|
end
|
91
107
|
end
|
92
108
|
end
|
@@ -15,13 +15,16 @@ module SidekiqRunner
|
|
15
15
|
RUNNER_ATTRIBUTES = [:config_file, :daemonize, :port, :syslog, :events]
|
16
16
|
RUNNER_ATTRIBUTES.each { |att| attr_accessor att }
|
17
17
|
|
18
|
-
CONFIG_FILE_ATTRIBUTES = [:process_name, :interval, :stop_timeout, :log_file]
|
18
|
+
CONFIG_FILE_ATTRIBUTES = [:process_name, :interval, :stop_timeout, :log_file, :log_level, :maximum_memory_usage, :pid]
|
19
19
|
CONFIG_FILE_ATTRIBUTES.each { |att| attr_accessor att }
|
20
20
|
|
21
|
+
attr_reader :generic_watchers
|
22
|
+
|
21
23
|
def initialize
|
22
24
|
@process_name = 'sidekiq'
|
23
25
|
@interval = 30
|
24
26
|
@stop_timeout = 30
|
27
|
+
@maximum_memory_usage = nil
|
25
28
|
|
26
29
|
@log_file = File.join(Dir.pwd, 'log', 'god.log')
|
27
30
|
@config_file = File.join(Dir.pwd, 'config', 'god.yml')
|
@@ -29,10 +32,18 @@ module SidekiqRunner
|
|
29
32
|
@daemonize = true
|
30
33
|
@syslog = true
|
31
34
|
@events = true
|
35
|
+
@pid = nil
|
36
|
+
@log_level = :warn
|
32
37
|
|
33
|
-
# This is going to be a part of the .sock file name e.g. "/tmp/god.17165.sock"
|
38
|
+
# This is going to be a part of the .sock file name e.g. "/tmp/god.17165.sock" and the pidfile name
|
34
39
|
# Change this in the configuration file to be able to run multiple instances of god.
|
35
40
|
@port = 17165
|
41
|
+
|
42
|
+
@generic_watchers = []
|
43
|
+
end
|
44
|
+
|
45
|
+
def add_generic(&blk)
|
46
|
+
@generic_watchers << blk
|
36
47
|
end
|
37
48
|
|
38
49
|
def options
|
@@ -44,7 +55,9 @@ module SidekiqRunner
|
|
44
55
|
syslog: @syslog,
|
45
56
|
events: @events,
|
46
57
|
config: File.expand_path("../sidekiq.god", __FILE__),
|
47
|
-
log: @log_file
|
58
|
+
log: @log_file,
|
59
|
+
pid: @pid,
|
60
|
+
log_level: @log_level
|
48
61
|
}
|
49
62
|
end
|
50
63
|
|
@@ -59,7 +72,15 @@ module SidekiqRunner
|
|
59
72
|
end
|
60
73
|
|
61
74
|
def create_directories!
|
62
|
-
FileUtils.mkdir_p(File.dirname(log_file))
|
75
|
+
FileUtils.mkdir_p(File.dirname(log_file)) if log_file
|
76
|
+
end
|
77
|
+
|
78
|
+
%w(start stop).each do |action|
|
79
|
+
attr_reader "before_#{action}_cb".to_sym
|
80
|
+
|
81
|
+
define_method("before_#{action}") do |&block|
|
82
|
+
instance_variable_set("@before_#{action}_cb".to_sym, block)
|
83
|
+
end
|
63
84
|
end
|
64
85
|
end
|
65
86
|
end
|
@@ -6,6 +6,12 @@ god_config = SidekiqRunner::GodConfiguration.get
|
|
6
6
|
|
7
7
|
God.terminate_timeout = god_config.stop_timeout + 10
|
8
8
|
|
9
|
+
god_config.generic_watchers.each do |block|
|
10
|
+
God.watch do |w|
|
11
|
+
block.call(w)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
9
15
|
sidekiq_config.each do |name, skiq|
|
10
16
|
God.watch do |w|
|
11
17
|
w.name = name
|
@@ -13,13 +19,15 @@ sidekiq_config.each do |name, skiq|
|
|
13
19
|
# Set start command.
|
14
20
|
w.start = skiq.build_start_command
|
15
21
|
|
22
|
+
# Set logfile
|
23
|
+
w.log = skiq.logfile
|
24
|
+
|
16
25
|
# Set stop command.
|
17
|
-
w.stop = skiq.build_stop_command(god_config.stop_timeout)
|
18
26
|
w.stop_timeout = god_config.stop_timeout
|
19
27
|
|
20
|
-
#
|
21
|
-
w.
|
22
|
-
w.
|
28
|
+
# Set uid/gid if requested.
|
29
|
+
w.uid = skiq.uid if skiq.uid
|
30
|
+
w.gid = skiq.gid if skiq.gid
|
23
31
|
|
24
32
|
# Working directory has to be set properly.
|
25
33
|
# Be aware that by default, God sets the working directory to / (root dir).
|
@@ -61,6 +69,21 @@ sidekiq_config.each do |name, skiq|
|
|
61
69
|
end
|
62
70
|
end
|
63
71
|
|
72
|
+
# Monitor process memory usage.
|
73
|
+
if god_config.maximum_memory_usage
|
74
|
+
w.restart_if do |restart|
|
75
|
+
restart.condition(:memory_usage) do |c|
|
76
|
+
c.above = god_config.maximum_memory_usage.to_i.megabytes
|
77
|
+
c.times = 3
|
78
|
+
c.interval = god_config.interval
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
if skiq.config_blocks.length > 0
|
84
|
+
skiq.config_blocks.each { |blk| blk.call(w) }
|
85
|
+
end
|
86
|
+
|
64
87
|
w.lifecycle do |on|
|
65
88
|
on.condition(:flapping) do |c|
|
66
89
|
c.to_state = [:start, :restart] # If this watch is started or restarted...
|
@@ -12,7 +12,7 @@ module SidekiqRunner
|
|
12
12
|
def initialize
|
13
13
|
@config_file =
|
14
14
|
if defined?(Rails)
|
15
|
-
File.join(Rails.root, 'config', 'sidekiq.yml')
|
15
|
+
File.join(Rails.root, 'config', 'sidekiq.yml')
|
16
16
|
else
|
17
17
|
File.join(Dir.pwd, 'config', 'sidekiq.yml')
|
18
18
|
end
|
@@ -86,8 +86,6 @@ module SidekiqRunner
|
|
86
86
|
end
|
87
87
|
|
88
88
|
def merge_config_file!
|
89
|
-
sidekiqs_common_config = {}
|
90
|
-
|
91
89
|
yml = File.exist?(config_file) ? YAML.load_file(config_file) : {}
|
92
90
|
yml = Hash[yml.map { |k, v| [k.to_sym, v] }]
|
93
91
|
|
@@ -96,8 +94,6 @@ module SidekiqRunner
|
|
96
94
|
|
97
95
|
def sane?
|
98
96
|
fail 'No sidekiq instances defined. Nothing to run.' if @sidekiqs.empty?
|
99
|
-
fail 'Sidekiq instances with the same pidfile found.' if @sidekiqs.values.map(&:pidfile).uniq.size < @sidekiqs.size
|
100
|
-
fail 'Sidekiq instances with the same logfile found.' if @sidekiqs.values.map(&:logfile).uniq.size < @sidekiqs.size
|
101
97
|
|
102
98
|
@sidekiqs.each_value { |skiq| skiq.sane? }
|
103
99
|
end
|
@@ -1,16 +1,15 @@
|
|
1
1
|
module SidekiqRunner
|
2
2
|
class SidekiqInstance
|
3
|
-
|
4
3
|
RUNNER_ATTRIBUTES = [:bundle_env, :chdir, :requirefile]
|
5
4
|
RUNNER_ATTRIBUTES.each { |att| attr_accessor att }
|
6
5
|
|
7
|
-
CONFIG_FILE_ATTRIBUTES = [:concurrency, :verbose, :pidfile, :logfile, :tag]
|
6
|
+
CONFIG_FILE_ATTRIBUTES = [:concurrency, :verbose, :pidfile, :logfile, :tag, :rbtrace, :uid, :gid]
|
8
7
|
CONFIG_FILE_ATTRIBUTES.each { |att| attr_accessor att }
|
9
8
|
|
10
|
-
attr_reader :name, :queues
|
9
|
+
attr_reader :name, :queues, :config_blocks
|
11
10
|
|
12
11
|
def initialize(name)
|
13
|
-
|
12
|
+
raise "No sidekiq instance name given!" if name.empty?
|
14
13
|
|
15
14
|
@name = name
|
16
15
|
@queues = []
|
@@ -23,15 +22,24 @@ module SidekiqRunner
|
|
23
22
|
@concurrency = 4
|
24
23
|
@verbose = false
|
25
24
|
@tag = name
|
25
|
+
@rbtrace = false
|
26
|
+
@uid = nil
|
27
|
+
@gid = nil
|
28
|
+
@config_blocks = []
|
26
29
|
end
|
27
30
|
|
28
31
|
def add_queue(queue_name, weight = 1)
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
+
raise "Cannot add the queue. The name is empty!" if queue_name.empty?
|
33
|
+
raise "Cannot add the queue. The weight is not an integer!" unless weight.is_a? Integer
|
34
|
+
raise "Cannot add the queue. The queue with \"#{queue_name}\" name already exist" if @queues.any? { |q| q.first == queue_name }
|
35
|
+
|
32
36
|
@queues << [queue_name, weight]
|
33
37
|
end
|
34
38
|
|
39
|
+
def god_config(&block)
|
40
|
+
@config_blocks << block
|
41
|
+
end
|
42
|
+
|
35
43
|
def merge_config_file!(yml)
|
36
44
|
# Get global configuration options.
|
37
45
|
SidekiqInstance::CONFIG_FILE_ATTRIBUTES.each do |k|
|
@@ -39,7 +47,7 @@ module SidekiqRunner
|
|
39
47
|
end
|
40
48
|
|
41
49
|
# Override with instance-specific options.
|
42
|
-
if (syml = yml[@name.to_sym]) &&
|
50
|
+
if (syml = yml[@name.to_sym]) && syml.is_a?(Hash)
|
43
51
|
syml = Hash[syml.map { |k, v| [k.to_sym, v] }]
|
44
52
|
|
45
53
|
SidekiqInstance::CONFIG_FILE_ATTRIBUTES.each do |k|
|
@@ -49,41 +57,30 @@ module SidekiqRunner
|
|
49
57
|
end
|
50
58
|
|
51
59
|
def sane?
|
52
|
-
|
53
|
-
|
60
|
+
raise "No queues given for #{@name}!" if @queues.empty?
|
61
|
+
raise "No requirefile given for #{@name} and not in Rails environment!" if !defined?(Rails) && !requirefile
|
54
62
|
end
|
55
63
|
|
56
64
|
def build_start_command
|
57
65
|
create_directories!
|
58
66
|
|
59
67
|
cmd = []
|
60
|
-
cmd <<
|
61
|
-
cmd << '
|
68
|
+
cmd << 'bundle exec' if bundle_env
|
69
|
+
cmd << (rbtrace ? File.expand_path('../../script/sidekiq_rbtrace', __dir__) : 'sidekiq')
|
62
70
|
cmd << "-c #{concurrency}"
|
63
71
|
cmd << '-v' if verbose
|
64
|
-
cmd << "-L #{logfile}"
|
65
72
|
cmd << "-P #{pidfile}"
|
66
73
|
cmd << "-e #{Rails.env}" if defined?(Rails)
|
67
74
|
cmd << "-r #{requirefile}" if requirefile
|
68
75
|
cmd << "-g '#{tag}'"
|
69
76
|
|
70
77
|
queues.each do |q, w|
|
71
|
-
cmd << "-q #{q},#{w
|
78
|
+
cmd << "-q #{q},#{w}"
|
72
79
|
end
|
73
80
|
|
74
81
|
cmd.join(' ')
|
75
82
|
end
|
76
83
|
|
77
|
-
def build_stop_command(timeout)
|
78
|
-
cmd = []
|
79
|
-
cmd << (bundle_env ? 'bundle exec sidekiqctl' : 'sidekiqctl')
|
80
|
-
cmd << 'stop'
|
81
|
-
cmd << pidfile
|
82
|
-
cmd << timeout
|
83
|
-
|
84
|
-
cmd.join(' ')
|
85
|
-
end
|
86
|
-
|
87
84
|
private
|
88
85
|
|
89
86
|
def create_directories!
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rbtrace'
|
4
|
+
|
5
|
+
def sidekiq_bin
|
6
|
+
require 'sidekiq/cli'
|
7
|
+
|
8
|
+
begin
|
9
|
+
cli = Sidekiq::CLI.instance
|
10
|
+
cli.parse
|
11
|
+
cli.run
|
12
|
+
rescue => e
|
13
|
+
raise e if $DEBUG
|
14
|
+
STDERR.puts e.message
|
15
|
+
STDERR.puts e.backtrace.join("\n")
|
16
|
+
exit 1
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
sidekiq = `which sidekiq` rescue ''
|
21
|
+
if sidekiq.empty?
|
22
|
+
# When we can't locate the Sidekiq executable, mimick
|
23
|
+
# its behaviour here.
|
24
|
+
sidekiq_bin
|
25
|
+
else
|
26
|
+
begin
|
27
|
+
# Otherwise load the sidekiq executable.
|
28
|
+
load sidekiq.strip
|
29
|
+
rescue
|
30
|
+
sidekiq_bin
|
31
|
+
end
|
32
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-runner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- FlavourSys Technology GmbH
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
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: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: god
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0.13'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sidekiq
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '6.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '6.0'
|
41
55
|
description: Provide an easy way to configure, start, and monitor all your Sidekiq
|
42
56
|
processes
|
43
57
|
email: technology@flavoursys.com
|
@@ -52,6 +66,7 @@ files:
|
|
52
66
|
- lib/sidekiq-runner/sidekiq_instance.rb
|
53
67
|
- lib/sidekiq-runner/tasks.rb
|
54
68
|
- lib/sidekiq-runner/version.rb
|
69
|
+
- script/sidekiq_rbtrace
|
55
70
|
homepage: https://github.com/FlavourSys/sidekiq-runner
|
56
71
|
licenses:
|
57
72
|
- MIT
|
@@ -72,7 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
87
|
version: '0'
|
73
88
|
requirements: []
|
74
89
|
rubyforge_project:
|
75
|
-
rubygems_version: 2.
|
90
|
+
rubygems_version: 2.7.6.2
|
76
91
|
signing_key:
|
77
92
|
specification_version: 4
|
78
93
|
summary: Sidekiq configuration and rake tasks
|