sidekiq-runner 0.0.3
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 +7 -0
- data/lib/sidekiq-runner.rb +98 -0
- data/lib/sidekiq-runner/common_configuration.rb +46 -0
- data/lib/sidekiq-runner/god_configuration.rb +39 -0
- data/lib/sidekiq-runner/sidekiq_command_builder.rb +31 -0
- data/lib/sidekiq-runner/sidekiq_configuration.rb +115 -0
- data/lib/sidekiq-runner/sidekiq_instance.rb +48 -0
- data/lib/sidekiq-runner/tasks.rb +20 -0
- data/lib/sidekiq-runner/version.rb +3 -0
- metadata +80 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ca0010af09c70a83fb3d9a7e19bb1fab9ab8c2d7
|
4
|
+
data.tar.gz: 2a56f515a2abc4174eca0e222161facc262d45bc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 30074809519b45508efeaa338146c1e601065f1e77c4d7df375d19e1ef67dfc4af440475f2643eb53146b3185092bd0ea361b944aa1683717471cfa2fa03c23f
|
7
|
+
data.tar.gz: c03238275cb23d3a27628abca14a087a22a0a9a519355525103392e05aed0f4039e87a3f7078fe8fdbb26d6c09e5057a434f1eae3d02d73ef0f5ea6d1c441eb8
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'sidekiq-runner/sidekiq_configuration'
|
2
|
+
require 'sidekiq-runner/god_configuration'
|
3
|
+
require 'sidekiq-runner/sidekiq_instance'
|
4
|
+
require 'sidekiq-runner/version'
|
5
|
+
|
6
|
+
module SidekiqRunner
|
7
|
+
def self.configure
|
8
|
+
yield SidekiqConfiguration.default if block_given?
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.configure_god
|
12
|
+
yield GodConfiguration.default if block_given?
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.start
|
16
|
+
sidekiq_config, god_config = get_all_settings
|
17
|
+
|
18
|
+
fail 'No sidekiq instances defined. There is nothing to run.' if sidekiq_config.empty?
|
19
|
+
|
20
|
+
abort 'God is running. I found an instance of a running god process. Please stop it manually and try again.' if god_alive?(god_config)
|
21
|
+
|
22
|
+
run(:start, sidekiq_config) do
|
23
|
+
puts 'Starting god.'
|
24
|
+
God::CLI::Run.new(god_config.options)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.stop
|
29
|
+
sidekiq_config, god_config = get_all_settings
|
30
|
+
|
31
|
+
run(:stop, sidekiq_config) do
|
32
|
+
God::EventHandler.load
|
33
|
+
|
34
|
+
if god_alive?(god_config)
|
35
|
+
puts "Stopping process #{god_config.process_name}."
|
36
|
+
|
37
|
+
# Stop all the processes
|
38
|
+
sidekiq_config.each_key do |name|
|
39
|
+
God::CLI::Command.new('stop', god_config.options, ['', name])
|
40
|
+
end
|
41
|
+
|
42
|
+
puts 'Terminating god.'
|
43
|
+
God::CLI::Command.new('terminate', god_config.options, [])
|
44
|
+
else
|
45
|
+
puts 'God is not running, so no need to stop it.'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.settings
|
51
|
+
SidekiqConfiguration.get.to_hash
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def self.get_all_settings
|
57
|
+
[SidekiqConfiguration.get, GodConfiguration.get]
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.god_alive?(god_config)
|
61
|
+
puts 'Checking whether god is alive...'
|
62
|
+
|
63
|
+
require 'drb'
|
64
|
+
require 'god/socket'
|
65
|
+
DRb.start_service('druby://127.0.0.1:0')
|
66
|
+
server = DRbObject.new(nil, God::Socket.socket(god_config.port))
|
67
|
+
|
68
|
+
# ping server to ensure that it is responsive
|
69
|
+
begin
|
70
|
+
server.ping
|
71
|
+
rescue DRb::DRbConnError
|
72
|
+
return false
|
73
|
+
end
|
74
|
+
true
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.run(action, sidekiq_config)
|
78
|
+
begin
|
79
|
+
# Use this flag to actually load all of the god infrastructure
|
80
|
+
$load_god = true
|
81
|
+
require 'god'
|
82
|
+
require 'god/cli/run'
|
83
|
+
|
84
|
+
# Peform the action
|
85
|
+
yield if block_given?
|
86
|
+
cb = nil
|
87
|
+
rescue SystemExit => e
|
88
|
+
cb = e.success? ? "#{action}_success_cb" : "#{action}_error_cb"
|
89
|
+
ensure
|
90
|
+
if [:start, :stop].include? action
|
91
|
+
cb = "#{action}_success_cb" unless cb
|
92
|
+
cb = sidekiq_config.send(cb.to_sym)
|
93
|
+
cb.call if cb
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module SidekiqRunner
|
4
|
+
|
5
|
+
# common functions for GodConfiguration and Configuration classes
|
6
|
+
class CommonConfiguration
|
7
|
+
# this method MUST be reimplemented
|
8
|
+
def self.default
|
9
|
+
fail(NotImplementedError, "Method \"#{__method__}\" is not implemented in \"#{name}\" class. Please DO implement this method to be able to derive from CommonConfiguration class.")
|
10
|
+
end
|
11
|
+
|
12
|
+
RUNNER_ATTRIBUTES = []
|
13
|
+
CONFIG_FILE_ATTRIBUTES = []
|
14
|
+
|
15
|
+
@config_file = ''
|
16
|
+
|
17
|
+
def to_hash
|
18
|
+
Hash[CONFIG_FILE_ATTRIBUTES.map { |att| [att, send(att)] }]
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.get
|
22
|
+
config = default.dup
|
23
|
+
config.send :merge_config_file!
|
24
|
+
config.send :sane?
|
25
|
+
config
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def merge_config_file!
|
31
|
+
if File.exist?(config_file)
|
32
|
+
yml = YAML.load_file(config_file)
|
33
|
+
CONFIG_FILE_ATTRIBUTES.each do |k|
|
34
|
+
v = yml[k] || yml[k.to_s]
|
35
|
+
send("#{k}=", v) unless v.nil?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
def sane?
|
43
|
+
end
|
44
|
+
|
45
|
+
end # class
|
46
|
+
end # module
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'sidekiq-runner/common_configuration'
|
2
|
+
|
3
|
+
module SidekiqRunner
|
4
|
+
class GodConfiguration < CommonConfiguration
|
5
|
+
def self.default
|
6
|
+
@default ||= GodConfiguration.new
|
7
|
+
end
|
8
|
+
|
9
|
+
RUNNER_ATTRIBUTES = [:config_file, :daemonize, :port, :syslog, :events, :options]
|
10
|
+
RUNNER_ATTRIBUTES.each { |att| attr_accessor att }
|
11
|
+
|
12
|
+
CONFIG_FILE_ATTRIBUTES = [:process_name, :interval, :stop_timeout, :log_file]
|
13
|
+
CONFIG_FILE_ATTRIBUTES.each { |att| attr_accessor att }
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@process_name = 'sidekiq'
|
17
|
+
@interval = 30
|
18
|
+
@stop_timeout = 30
|
19
|
+
@log_file = File.join(Dir.pwd, 'log', 'god.log')
|
20
|
+
|
21
|
+
@config_file = File.join(Dir.pwd, 'config', 'god.yml')
|
22
|
+
@daemonize = true
|
23
|
+
# This is going to be a part of the .sock file name e.g. "/tmp/god.17165.sock"
|
24
|
+
# Change this in the configuration file to be able to run multiple instances of god
|
25
|
+
@port = 17165
|
26
|
+
@syslog = true
|
27
|
+
@events = true
|
28
|
+
@options = {
|
29
|
+
daemonize: @daemonize,
|
30
|
+
port: @port,
|
31
|
+
syslog: @syslog,
|
32
|
+
events: @events,
|
33
|
+
config: File.expand_path("../#{@process_name}.god", __FILE__),
|
34
|
+
log: @log_file
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module SidekiqCommandBuilder
|
2
|
+
|
3
|
+
def self.build_start_command(sidekiq_config, skiq)
|
4
|
+
cmd = []
|
5
|
+
cmd << (skiq.bundle_env ? 'bundle exec sidekiq' : 'sidekiq')
|
6
|
+
cmd << '-d' if sidekiq_config.daemonize
|
7
|
+
cmd << "-c #{skiq.concurrency}"
|
8
|
+
cmd << "-e #{Rails.env}" if defined?(Rails)
|
9
|
+
cmd << '-v' if skiq.verbose
|
10
|
+
cmd << "-L #{skiq.logfile}"
|
11
|
+
cmd << "-P #{skiq.pidfile}"
|
12
|
+
cmd << "-r #{skiq.requirefile}" if skiq.requirefile
|
13
|
+
|
14
|
+
skiq.queues.each do |q, w|
|
15
|
+
cmd << "-q #{q},#{w.to_s}"
|
16
|
+
end
|
17
|
+
|
18
|
+
cmd.join(' ')
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.build_stop_command(skiq, timeout)
|
22
|
+
cmd = []
|
23
|
+
cmd << (skiq.bundle_env ? 'bundle exec sidekiqctl' : 'sidekiqctl')
|
24
|
+
cmd << 'stop'
|
25
|
+
cmd << skiq.pidfile
|
26
|
+
cmd << timeout
|
27
|
+
|
28
|
+
cmd.join(' ')
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'sidekiq-runner/common_configuration'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module SidekiqRunner
|
5
|
+
class SidekiqConfiguration < CommonConfiguration
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
RUNNER_ATTRIBUTES = [:config_file, :daemonize]
|
9
|
+
RUNNER_ATTRIBUTES.each { |att| attr_accessor att }
|
10
|
+
|
11
|
+
attr_reader :sidekiqs
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@config_file = File.join(Dir.pwd, 'config', 'sidekiq.yml')
|
15
|
+
@daemonize = true
|
16
|
+
|
17
|
+
@sidekiqs = {}
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.default
|
21
|
+
@default ||= SidekiqConfiguration.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def each(&block)
|
25
|
+
@sidekiqs.each(&block)
|
26
|
+
end
|
27
|
+
|
28
|
+
def each_key(&block)
|
29
|
+
@sidekiqs.each_key(&block)
|
30
|
+
end
|
31
|
+
|
32
|
+
def empty?
|
33
|
+
@sidekiqs.empty?
|
34
|
+
end
|
35
|
+
|
36
|
+
# DELETEME in the future
|
37
|
+
# Redefined and kept for bakward compatibility
|
38
|
+
def queue(name, weight = 1)
|
39
|
+
# Create a default sidekiq instance when no instances were created
|
40
|
+
fail 'Sidekiq instances hash does not seem to be empty.
|
41
|
+
It means you are using the newer syntax in the initializer to create at least one instance.
|
42
|
+
Therefore you should not be using the old queue() function.' unless @sidekiqs.empty?
|
43
|
+
|
44
|
+
add_instance('sidekiq_default') do |skiq|
|
45
|
+
skiq.add_queue('default')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def add_instance(name)
|
50
|
+
skiq = SidekiqInstance.new(name)
|
51
|
+
yield skiq if block_given?
|
52
|
+
|
53
|
+
fail "Sidekick instance with the name of #{name} already exists! No duplicates please." if @sidekiqs.has_key?(name)
|
54
|
+
|
55
|
+
FileUtils.mkdir_p(File.dirname(skiq.pidfile))
|
56
|
+
FileUtils.mkdir_p(File.dirname(skiq.logfile))
|
57
|
+
|
58
|
+
@sidekiqs[name] = skiq
|
59
|
+
|
60
|
+
skiq
|
61
|
+
end
|
62
|
+
|
63
|
+
%w(start stop).each do |action|
|
64
|
+
%w(success error).each do |state|
|
65
|
+
attr_reader "#{action}_#{state}_cb".to_sym
|
66
|
+
|
67
|
+
define_method("on_#{action}_#{state}") do |&block|
|
68
|
+
instance_variable_set("@#{action}_#{state}_cb".to_sym, block)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def merge_config_file!
|
76
|
+
sidekiqs_common_config = {}
|
77
|
+
yml = {}
|
78
|
+
|
79
|
+
if File.exist?(config_file)
|
80
|
+
yml = YAML.load_file(config_file)
|
81
|
+
# Get sidekiq config common for all instances
|
82
|
+
SidekiqInstance::CONFIG_FILE_ATTRIBUTES.each do |k|
|
83
|
+
v = yml[k] || yml[k.to_s]
|
84
|
+
sidekiqs_common_config[k] = v if v
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Backwards compatibility
|
89
|
+
# Get sidekiq pidfile and logfile if no sidekiq instance was specified
|
90
|
+
SidekiqInstance::INDIVIDUAL_FILE_ATTRIBUTES.each do |k|
|
91
|
+
v = yml[k] || yml[k.to_s]
|
92
|
+
sidekiqs_common_config[k] = v if v
|
93
|
+
end
|
94
|
+
|
95
|
+
@sidekiqs.each do |name, skiq|
|
96
|
+
# Symbolize keys in yml hash
|
97
|
+
if yml[name] && yml[name].is_a?(Hash)
|
98
|
+
yml_config = Hash[yml[name].map { |k, v| [k.to_sym, v] }]
|
99
|
+
end
|
100
|
+
# Merge common and specific sidekiq instance configs
|
101
|
+
# Sidekiq instances not defined in the initializer but present in yml will be ignored
|
102
|
+
final_skiq_config = yml_config ? sidekiqs_common_config.merge(yml_config) : sidekiqs_common_config
|
103
|
+
skiq.merge_config!(final_skiq_config)
|
104
|
+
skiq.sane?
|
105
|
+
end
|
106
|
+
|
107
|
+
self
|
108
|
+
end
|
109
|
+
|
110
|
+
def sane?
|
111
|
+
fail 'No requirefile given and not in Rails env.' if !defined?(Rails) && !requirefile
|
112
|
+
fail 'No sidekiq instances defined. Nothing to run.' if @sidekiqs.empty?
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module SidekiqRunner
|
2
|
+
class SidekiqInstance
|
3
|
+
|
4
|
+
CONFIG_FILE_ATTRIBUTES = [:bundle_env, :chdir, :requirefile, :concurrency, :verbose]
|
5
|
+
INDIVIDUAL_FILE_ATTRIBUTES = [:pidfile, :logfile]
|
6
|
+
CONFIG_FILE_ATTRIBUTES.concat(INDIVIDUAL_FILE_ATTRIBUTES).each { |att| attr_accessor att }
|
7
|
+
|
8
|
+
attr_reader :name, :queues
|
9
|
+
|
10
|
+
def initialize(name)
|
11
|
+
fail "No sidekiq instance name given!" if name.empty?
|
12
|
+
|
13
|
+
@name = name
|
14
|
+
@queues = []
|
15
|
+
|
16
|
+
@bundle_env = true
|
17
|
+
@daemonize = true
|
18
|
+
@chdir = nil
|
19
|
+
@requirefile = nil
|
20
|
+
@pidfile = File.join(Dir.pwd, 'tmp', 'pids', "#{@name}.pid")
|
21
|
+
@logfile = File.join(Dir.pwd, 'log', "#{@name}.log")
|
22
|
+
@concurrency = 4
|
23
|
+
@verbose = false
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
def add_queue(queue_name, weight = 1)
|
28
|
+
fail "Cannot add the queue. The name is empty!" if queue_name.empty?
|
29
|
+
fail "Cannot add the queue. The weight is not an integer!" unless weight.is_a? Integer
|
30
|
+
fail "Cannot add the queue. The queue with \"#{queue_name}\" name already exist" if @queues.any?{|arr| arr.first == queue_name}
|
31
|
+
@queues << [queue_name, weight]
|
32
|
+
end
|
33
|
+
|
34
|
+
def sane?
|
35
|
+
fail "No queues given for #{@name}!" if @queues.empty?
|
36
|
+
end
|
37
|
+
|
38
|
+
def merge_config!(skiq)
|
39
|
+
CONFIG_FILE_ATTRIBUTES.each do |k|
|
40
|
+
v = nil || skiq[k]
|
41
|
+
send("#{k}=", v) unless v.nil?
|
42
|
+
end
|
43
|
+
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'sidekiq-runner'
|
2
|
+
|
3
|
+
rails_env = Rake::Task.task_defined?(:environment) ? [:environment] : []
|
4
|
+
|
5
|
+
namespace :sidekiqrunner do
|
6
|
+
desc 'Start sidekiq-runner instances'
|
7
|
+
task start: rails_env do
|
8
|
+
puts 'Starting sidekiq instances...'
|
9
|
+
SidekiqRunner.start
|
10
|
+
end
|
11
|
+
|
12
|
+
desc 'Stop sidekiq-runner instances'
|
13
|
+
task stop: rails_env do
|
14
|
+
puts 'Gracefully shutting down sidekiq instances...'
|
15
|
+
SidekiqRunner.stop
|
16
|
+
end
|
17
|
+
|
18
|
+
desc 'Restart sidekiq-runner instances'
|
19
|
+
task restart: ['sidekiq:stop', 'sidekiq:start']
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sidekiq-runner
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- FlavourSys Technology GmbH
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-07-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '10.3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '10.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: god
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.13'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.13'
|
41
|
+
description: A little collection of Sidekiq start/stop rake tasks and configuration
|
42
|
+
framework
|
43
|
+
email: technology@flavoursys.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- lib/sidekiq-runner.rb
|
49
|
+
- lib/sidekiq-runner/common_configuration.rb
|
50
|
+
- lib/sidekiq-runner/god_configuration.rb
|
51
|
+
- lib/sidekiq-runner/sidekiq_command_builder.rb
|
52
|
+
- lib/sidekiq-runner/sidekiq_configuration.rb
|
53
|
+
- lib/sidekiq-runner/sidekiq_instance.rb
|
54
|
+
- lib/sidekiq-runner/tasks.rb
|
55
|
+
- lib/sidekiq-runner/version.rb
|
56
|
+
homepage: http://flavoursys.com
|
57
|
+
licenses:
|
58
|
+
- MIT
|
59
|
+
metadata: {}
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
requirements: []
|
75
|
+
rubyforge_project:
|
76
|
+
rubygems_version: 2.2.2
|
77
|
+
signing_key:
|
78
|
+
specification_version: 4
|
79
|
+
summary: Sidekiq rake task collection
|
80
|
+
test_files: []
|