kulesa-sidekiq 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (135) hide show
  1. data/.gitignore +6 -0
  2. data/.rvmrc +4 -0
  3. data/COMM-LICENSE +83 -0
  4. data/Changes.md +207 -0
  5. data/Gemfile +12 -0
  6. data/LICENSE +22 -0
  7. data/README.md +61 -0
  8. data/Rakefile +9 -0
  9. data/bin/client +7 -0
  10. data/bin/sidekiq +14 -0
  11. data/bin/sidekiqctl +74 -0
  12. data/config.ru +18 -0
  13. data/examples/chef/cookbooks/sidekiq/README.rdoc +11 -0
  14. data/examples/chef/cookbooks/sidekiq/recipes/default.rb +55 -0
  15. data/examples/chef/cookbooks/sidekiq/templates/default/monitrc.conf.erb +8 -0
  16. data/examples/chef/cookbooks/sidekiq/templates/default/sidekiq.erb +219 -0
  17. data/examples/chef/cookbooks/sidekiq/templates/default/sidekiq.yml.erb +22 -0
  18. data/examples/clockwork.rb +44 -0
  19. data/examples/config.yml +10 -0
  20. data/examples/monitrc.conf +6 -0
  21. data/examples/por.rb +27 -0
  22. data/examples/scheduling.rb +37 -0
  23. data/examples/sinkiq.rb +59 -0
  24. data/examples/web-ui.png +0 -0
  25. data/lib/sidekiq.rb +98 -0
  26. data/lib/sidekiq/capistrano.rb +35 -0
  27. data/lib/sidekiq/cli.rb +214 -0
  28. data/lib/sidekiq/client.rb +72 -0
  29. data/lib/sidekiq/extensions/action_mailer.rb +26 -0
  30. data/lib/sidekiq/extensions/active_record.rb +27 -0
  31. data/lib/sidekiq/extensions/generic_proxy.rb +21 -0
  32. data/lib/sidekiq/fetch.rb +76 -0
  33. data/lib/sidekiq/logging.rb +46 -0
  34. data/lib/sidekiq/manager.rb +163 -0
  35. data/lib/sidekiq/middleware/chain.rb +96 -0
  36. data/lib/sidekiq/middleware/client/unique_jobs.rb +36 -0
  37. data/lib/sidekiq/middleware/server/active_record.rb +13 -0
  38. data/lib/sidekiq/middleware/server/exception_handler.rb +38 -0
  39. data/lib/sidekiq/middleware/server/failure_jobs.rb +25 -0
  40. data/lib/sidekiq/middleware/server/logging.rb +31 -0
  41. data/lib/sidekiq/middleware/server/retry_jobs.rb +69 -0
  42. data/lib/sidekiq/middleware/server/timeout.rb +21 -0
  43. data/lib/sidekiq/middleware/server/unique_jobs.rb +17 -0
  44. data/lib/sidekiq/processor.rb +92 -0
  45. data/lib/sidekiq/rails.rb +21 -0
  46. data/lib/sidekiq/redis_connection.rb +27 -0
  47. data/lib/sidekiq/retry.rb +59 -0
  48. data/lib/sidekiq/testing.rb +44 -0
  49. data/lib/sidekiq/testing/inline.rb +37 -0
  50. data/lib/sidekiq/util.rb +40 -0
  51. data/lib/sidekiq/version.rb +3 -0
  52. data/lib/sidekiq/web.rb +185 -0
  53. data/lib/sidekiq/worker.rb +62 -0
  54. data/lib/sidekiq/yaml_patch.rb +21 -0
  55. data/myapp/.gitignore +15 -0
  56. data/myapp/Capfile +5 -0
  57. data/myapp/Gemfile +19 -0
  58. data/myapp/Rakefile +7 -0
  59. data/myapp/app/controllers/application_controller.rb +3 -0
  60. data/myapp/app/controllers/work_controller.rb +38 -0
  61. data/myapp/app/helpers/application_helper.rb +2 -0
  62. data/myapp/app/mailers/.gitkeep +0 -0
  63. data/myapp/app/mailers/user_mailer.rb +9 -0
  64. data/myapp/app/models/.gitkeep +0 -0
  65. data/myapp/app/models/post.rb +5 -0
  66. data/myapp/app/views/layouts/application.html.erb +14 -0
  67. data/myapp/app/views/user_mailer/greetings.html.erb +3 -0
  68. data/myapp/app/views/work/index.html.erb +1 -0
  69. data/myapp/app/workers/hard_worker.rb +10 -0
  70. data/myapp/config.ru +4 -0
  71. data/myapp/config/application.rb +59 -0
  72. data/myapp/config/boot.rb +6 -0
  73. data/myapp/config/database.yml +25 -0
  74. data/myapp/config/deploy.rb +15 -0
  75. data/myapp/config/environment.rb +5 -0
  76. data/myapp/config/environments/development.rb +38 -0
  77. data/myapp/config/environments/production.rb +67 -0
  78. data/myapp/config/environments/test.rb +37 -0
  79. data/myapp/config/initializers/backtrace_silencers.rb +7 -0
  80. data/myapp/config/initializers/inflections.rb +15 -0
  81. data/myapp/config/initializers/mime_types.rb +5 -0
  82. data/myapp/config/initializers/secret_token.rb +7 -0
  83. data/myapp/config/initializers/session_store.rb +8 -0
  84. data/myapp/config/initializers/sidekiq.rb +6 -0
  85. data/myapp/config/initializers/wrap_parameters.rb +14 -0
  86. data/myapp/config/locales/en.yml +5 -0
  87. data/myapp/config/routes.rb +10 -0
  88. data/myapp/db/migrate/20120123214055_create_posts.rb +10 -0
  89. data/myapp/db/seeds.rb +7 -0
  90. data/myapp/lib/assets/.gitkeep +0 -0
  91. data/myapp/lib/tasks/.gitkeep +0 -0
  92. data/myapp/log/.gitkeep +0 -0
  93. data/myapp/script/rails +6 -0
  94. data/sidekiq.gemspec +27 -0
  95. data/test/config.yml +9 -0
  96. data/test/fake_env.rb +0 -0
  97. data/test/helper.rb +16 -0
  98. data/test/test_cli.rb +168 -0
  99. data/test/test_client.rb +119 -0
  100. data/test/test_extensions.rb +69 -0
  101. data/test/test_manager.rb +51 -0
  102. data/test/test_middleware.rb +92 -0
  103. data/test/test_processor.rb +32 -0
  104. data/test/test_retry.rb +125 -0
  105. data/test/test_stats.rb +68 -0
  106. data/test/test_testing.rb +97 -0
  107. data/test/test_testing_inline.rb +75 -0
  108. data/test/test_web.rb +122 -0
  109. data/web/assets/images/bootstrap/glyphicons-halflings-white.png +0 -0
  110. data/web/assets/images/bootstrap/glyphicons-halflings.png +0 -0
  111. data/web/assets/javascripts/application.js +20 -0
  112. data/web/assets/javascripts/vendor/bootstrap.js +12 -0
  113. data/web/assets/javascripts/vendor/bootstrap/bootstrap-alert.js +91 -0
  114. data/web/assets/javascripts/vendor/bootstrap/bootstrap-button.js +98 -0
  115. data/web/assets/javascripts/vendor/bootstrap/bootstrap-carousel.js +154 -0
  116. data/web/assets/javascripts/vendor/bootstrap/bootstrap-collapse.js +136 -0
  117. data/web/assets/javascripts/vendor/bootstrap/bootstrap-dropdown.js +92 -0
  118. data/web/assets/javascripts/vendor/bootstrap/bootstrap-modal.js +210 -0
  119. data/web/assets/javascripts/vendor/bootstrap/bootstrap-popover.js +95 -0
  120. data/web/assets/javascripts/vendor/bootstrap/bootstrap-scrollspy.js +125 -0
  121. data/web/assets/javascripts/vendor/bootstrap/bootstrap-tab.js +130 -0
  122. data/web/assets/javascripts/vendor/bootstrap/bootstrap-tooltip.js +270 -0
  123. data/web/assets/javascripts/vendor/bootstrap/bootstrap-transition.js +51 -0
  124. data/web/assets/javascripts/vendor/bootstrap/bootstrap-typeahead.js +271 -0
  125. data/web/assets/javascripts/vendor/jquery.js +9266 -0
  126. data/web/assets/javascripts/vendor/jquery.timeago.js +148 -0
  127. data/web/assets/stylesheets/application.css +27 -0
  128. data/web/assets/stylesheets/vendor/bootstrap-responsive.css +567 -0
  129. data/web/assets/stylesheets/vendor/bootstrap.css +3365 -0
  130. data/web/views/index.slim +48 -0
  131. data/web/views/layout.slim +26 -0
  132. data/web/views/queue.slim +11 -0
  133. data/web/views/retries.slim +29 -0
  134. data/web/views/retry.slim +52 -0
  135. metadata +371 -0
@@ -0,0 +1,59 @@
1
+ # Make sure you have Sinatra installed, then start sidekiq with
2
+ # ./bin/sidekiq -r ./examples/sinkiq.rb
3
+ # Simply run Sinatra with
4
+ # ruby examples/sinkiq.rb
5
+ # and then browse to http://localhost:4567
6
+ #
7
+ require 'sinatra'
8
+ require 'sidekiq'
9
+ require 'redis'
10
+
11
+ $redis = Redis.connect
12
+
13
+ class SinatraWorker
14
+ include Sidekiq::Worker
15
+
16
+ def perform(msg="lulz you forgot a msg!")
17
+ $redis.lpush("sinkiq-example-messages", msg)
18
+ end
19
+ end
20
+
21
+ get '/' do
22
+ @failed = $redis.get('stat:failed')
23
+ @processed = $redis.get('stat:processed')
24
+ @messages = $redis.lrange('sinkiq-example-messages', 0, -1)
25
+ erb :index
26
+ end
27
+
28
+ post '/msg' do
29
+ SinatraWorker.perform_async params[:msg]
30
+ redirect to('/')
31
+ end
32
+
33
+ __END__
34
+
35
+ @@ layout
36
+ <html>
37
+ <head>
38
+ <title>Sinatra + Sidekiq</title>
39
+ <body>
40
+ <%= yield %>
41
+ </body>
42
+ </html>
43
+
44
+ @@ index
45
+ <h1>Sinatra + Sidekiq Example</h1>
46
+ <h2>Failed: <%= @failed %></h2>
47
+ <h2>Processed: <%= @processed %></h2>
48
+
49
+ <form method="post" action="/msg">
50
+ <input type="text" name="msg">
51
+ <input type="submit" value="Add Message">
52
+ </form>
53
+
54
+ <a href="/">Refresh page</a>
55
+
56
+ <h3>Messages</h3>
57
+ <% @messages.each do |msg| %>
58
+ <p><%= msg %></p>
59
+ <% end %>
Binary file
@@ -0,0 +1,98 @@
1
+ require 'sidekiq/version'
2
+ require 'sidekiq/logging'
3
+ require 'sidekiq/client'
4
+ require 'sidekiq/worker'
5
+ require 'sidekiq/redis_connection'
6
+ require 'sidekiq/util'
7
+
8
+ require 'sidekiq/extensions/action_mailer'
9
+ require 'sidekiq/extensions/active_record'
10
+ require 'sidekiq/rails' if defined?(::Rails)
11
+
12
+ module Sidekiq
13
+
14
+ DEFAULTS = {
15
+ :queues => [],
16
+ :concurrency => 25,
17
+ :require => '.',
18
+ :environment => nil,
19
+ :timeout => 8,
20
+ :enable_rails_extensions => true,
21
+ }
22
+
23
+ def self.options
24
+ @options ||= DEFAULTS.dup
25
+ end
26
+
27
+ def self.options=(opts)
28
+ @options = opts
29
+ end
30
+
31
+ ##
32
+ # Configuration for Sidekiq server, use like:
33
+ #
34
+ # Sidekiq.configure_server do |config|
35
+ # config.redis = { :namespace => 'myapp', :size => 25, :url => 'redis://myhost:8877/mydb' }
36
+ # config.server_middleware do |chain|
37
+ # chain.add MyServerHook
38
+ # end
39
+ # end
40
+ def self.configure_server
41
+ yield self if server?
42
+ end
43
+
44
+ ##
45
+ # Configuration for Sidekiq client, use like:
46
+ #
47
+ # Sidekiq.configure_client do |config|
48
+ # config.redis = { :namespace => 'myapp', :size => 1, :url => 'redis://myhost:8877/mydb' }
49
+ # end
50
+ def self.configure_client
51
+ yield self unless server?
52
+ end
53
+
54
+ def self.server?
55
+ defined?(Sidekiq::CLI)
56
+ end
57
+
58
+ def self.redis(&block)
59
+ @redis ||= Sidekiq::RedisConnection.create
60
+ raise ArgumentError, "requires a block" if !block
61
+ @redis.with(&block)
62
+ end
63
+
64
+ def self.redis=(hash)
65
+ if hash.is_a?(Hash)
66
+ @redis = RedisConnection.create(hash)
67
+ elsif hash.is_a?(ConnectionPool)
68
+ @redis = hash
69
+ else
70
+ raise ArgumentError, "redis= requires a Hash or ConnectionPool"
71
+ end
72
+ end
73
+
74
+ def self.client_middleware
75
+ @client_chain ||= Client.default_middleware
76
+ yield @client_chain if block_given?
77
+ @client_chain
78
+ end
79
+
80
+ def self.server_middleware
81
+ @server_chain ||= Processor.default_middleware
82
+ yield @server_chain if block_given?
83
+ @server_chain
84
+ end
85
+
86
+ def self.load_json(string)
87
+ MultiJson.decode(string)
88
+ end
89
+
90
+ def self.dump_json(object)
91
+ MultiJson.encode(object)
92
+ end
93
+
94
+ def self.logger
95
+ Sidekiq::Logging.logger
96
+ end
97
+
98
+ end
@@ -0,0 +1,35 @@
1
+ Capistrano::Configuration.instance.load do
2
+ before "deploy", "sidekiq:quiet"
3
+ after "deploy:stop", "sidekiq:stop"
4
+ after "deploy:start", "sidekiq:start"
5
+ after "deploy:restart", "sidekiq:restart"
6
+
7
+ _cset(:sidekiq_timeout) { 10 }
8
+ _cset(:sidekiq_role) { :app }
9
+
10
+ namespace :sidekiq do
11
+
12
+ desc "Quiet sidekiq (stop accepting new work)"
13
+ task :quiet, :roles => lambda { fetch(:sidekiq_role) }, :on_no_matching_servers => :continue do
14
+ run "cd #{current_path} && if [ -f #{current_path}/tmp/pids/sidekiq.pid ]; then #{fetch(:bundle_cmd, "bundle")} exec sidekiqctl quiet #{current_path}/tmp/pids/sidekiq.pid ; fi"
15
+ end
16
+
17
+ desc "Stop sidekiq"
18
+ task :stop, :roles => lambda { fetch(:sidekiq_role) }, :on_no_matching_servers => :continue do
19
+ run "cd #{current_path} && if [ -f #{current_path}/tmp/pids/sidekiq.pid ]; then #{fetch(:bundle_cmd, "bundle")} exec sidekiqctl stop #{current_path}/tmp/pids/sidekiq.pid #{fetch :sidekiq_timeout} ; fi"
20
+ end
21
+
22
+ desc "Start sidekiq"
23
+ task :start, :roles => lambda { fetch(:sidekiq_role) }, :on_no_matching_servers => :continue do
24
+ rails_env = fetch(:rails_env, "production")
25
+ run "cd #{current_path} ; nohup #{fetch(:bundle_cmd, "bundle")} exec sidekiq -e #{rails_env} -C #{current_path}/config/sidekiq.yml -P #{current_path}/tmp/pids/sidekiq.pid >> #{current_path}/log/sidekiq.log 2>&1 &", :pty => false
26
+ end
27
+
28
+ desc "Restart sidekiq"
29
+ task :restart, :roles => lambda { fetch(:sidekiq_role) }, :on_no_matching_servers => :continue do
30
+ stop
31
+ start
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,214 @@
1
+ trap 'INT' do
2
+ # Handle Ctrl-C in JRuby like MRI
3
+ # http://jira.codehaus.org/browse/JRUBY-4637
4
+ Sidekiq::CLI.instance.interrupt
5
+ end
6
+
7
+ trap 'TERM' do
8
+ # Heroku sends TERM and then waits 10 seconds for process to exit.
9
+ Sidekiq::CLI.instance.interrupt
10
+ end
11
+
12
+ trap 'USR1' do
13
+ Sidekiq.logger.info "Received USR1, no longer accepting new work"
14
+ mgr = Sidekiq::CLI.instance.manager
15
+ mgr.stop! if mgr
16
+ end
17
+
18
+ trap 'TTIN' do
19
+ Thread.list.each do |thread|
20
+ puts "Thread TID-#{thread.object_id.to_s(36)} #{thread['label']}"
21
+ puts thread.backtrace.join("\n")
22
+ end
23
+ end
24
+
25
+ require 'yaml'
26
+ require 'singleton'
27
+ require 'optparse'
28
+ require 'celluloid'
29
+
30
+ require 'sidekiq'
31
+ require 'sidekiq/util'
32
+ require 'sidekiq/manager'
33
+ require 'sidekiq/retry'
34
+
35
+ module Sidekiq
36
+ class CLI
37
+ include Util
38
+ include Singleton
39
+
40
+ # Used for CLI testing
41
+ attr_accessor :code
42
+ attr_accessor :manager
43
+
44
+ def initialize
45
+ @code = nil
46
+ @interrupt_mutex = Mutex.new
47
+ @interrupted = false
48
+ end
49
+
50
+ def parse(args=ARGV)
51
+ @code = nil
52
+ Sidekiq.logger
53
+
54
+ cli = parse_options(args)
55
+ config = parse_config(cli)
56
+ options.merge!(config.merge(cli))
57
+
58
+ Sidekiq.logger.level = Logger::DEBUG if options[:verbose]
59
+ Celluloid.logger = nil
60
+
61
+ validate!
62
+ write_pid
63
+ boot_system
64
+ end
65
+
66
+ def run
67
+ @manager = Sidekiq::Manager.new(options)
68
+ poller = Sidekiq::Retry::Poller.new
69
+ begin
70
+ logger.info 'Starting processing, hit Ctrl-C to stop'
71
+ @manager.start!
72
+ poller.poll!
73
+ sleep
74
+ rescue Interrupt
75
+ logger.info 'Shutting down'
76
+ poller.terminate! if poller.alive?
77
+ @manager.stop!(:shutdown => true, :timeout => options[:timeout])
78
+ @manager.wait(:shutdown)
79
+ # Explicitly exit so busy Processor threads can't block
80
+ # process shutdown.
81
+ exit(0)
82
+ end
83
+ end
84
+
85
+ def interrupt
86
+ @interrupt_mutex.synchronize do
87
+ unless @interrupted
88
+ @interrupted = true
89
+ Thread.main.raise Interrupt
90
+ end
91
+ end
92
+ end
93
+
94
+ private
95
+
96
+ def die(code)
97
+ exit(code)
98
+ end
99
+
100
+ def options
101
+ Sidekiq.options
102
+ end
103
+
104
+ def detected_environment
105
+ options[:environment] ||= ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
106
+ end
107
+
108
+ def boot_system
109
+ ENV['RACK_ENV'] = ENV['RAILS_ENV'] = detected_environment
110
+
111
+ raise ArgumentError, "#{options[:require]} does not exist" unless File.exist?(options[:require])
112
+
113
+ if File.directory?(options[:require])
114
+ require 'rails'
115
+ require 'sidekiq/rails'
116
+ require File.expand_path("#{options[:require]}/config/environment.rb")
117
+ ::Rails.application.eager_load!
118
+ else
119
+ require options[:require]
120
+ end
121
+ end
122
+
123
+ def validate!
124
+ options[:queues] << 'default' if options[:queues].empty?
125
+ options[:queues].shuffle!
126
+
127
+ if !File.exist?(options[:require]) ||
128
+ (File.directory?(options[:require]) && !File.exist?("#{options[:require]}/config/application.rb"))
129
+ logger.info "=================================================================="
130
+ logger.info " Please point sidekiq to a Rails 3 application or a Ruby file "
131
+ logger.info " to load your worker classes with -r [DIR|FILE]."
132
+ logger.info "=================================================================="
133
+ logger.info @parser
134
+ die(1)
135
+ end
136
+ end
137
+
138
+ def parse_options(argv)
139
+ opts = {}
140
+
141
+ @parser = OptionParser.new do |o|
142
+ o.on "-q", "--queue QUEUE,WEIGHT", "Queue to process, with optional weight" do |arg|
143
+ q, weight = arg.split(",")
144
+ parse_queues(opts, q, weight)
145
+ end
146
+
147
+ o.on "-v", "--verbose", "Print more verbose output" do
148
+ Sidekiq.logger.level = ::Logger::DEBUG
149
+ end
150
+
151
+ o.on '-e', '--environment ENV', "Application environment" do |arg|
152
+ opts[:environment] = arg
153
+ end
154
+
155
+ o.on '-t', '--timeout NUM', "Shutdown timeout" do |arg|
156
+ opts[:timeout] = arg.to_i
157
+ end
158
+
159
+ o.on '-r', '--require [PATH|DIR]', "Location of Rails application with workers or file to require" do |arg|
160
+ opts[:require] = arg
161
+ end
162
+
163
+ o.on '-c', '--concurrency INT', "processor threads to use" do |arg|
164
+ opts[:concurrency] = arg.to_i
165
+ end
166
+
167
+ o.on '-P', '--pidfile PATH', "path to pidfile" do |arg|
168
+ opts[:pidfile] = arg
169
+ end
170
+
171
+ o.on '-C', '--config PATH', "path to YAML config file" do |arg|
172
+ opts[:config_file] = arg
173
+ end
174
+
175
+ o.on '-V', '--version', "Print version and exit" do |arg|
176
+ puts "Sidekiq #{Sidekiq::VERSION}"
177
+ die(0)
178
+ end
179
+ end
180
+
181
+ @parser.banner = "sidekiq [options]"
182
+ @parser.on_tail "-h", "--help", "Show help" do
183
+ logger.info @parser
184
+ die 1
185
+ end
186
+ @parser.parse!(argv)
187
+ opts
188
+ end
189
+
190
+ def write_pid
191
+ if path = options[:pidfile]
192
+ File.open(path, 'w') do |f|
193
+ f.puts Process.pid
194
+ end
195
+ end
196
+ end
197
+
198
+ def parse_config(cli)
199
+ opts = {}
200
+ if cli[:config_file] && File.exist?(cli[:config_file])
201
+ opts = YAML.load_file cli[:config_file]
202
+ queues = opts.delete(:queues) || []
203
+ queues.each { |name, weight| parse_queues(opts, name, weight) }
204
+ end
205
+ opts
206
+ end
207
+
208
+ def parse_queues(opts, q, weight)
209
+ (weight || 1).to_i.times do
210
+ (opts[:queues] ||= []) << q
211
+ end
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,72 @@
1
+ require 'multi_json'
2
+
3
+ require 'sidekiq/middleware/chain'
4
+ require 'sidekiq/middleware/client/unique_jobs'
5
+
6
+ module Sidekiq
7
+ class Client
8
+
9
+ def self.default_middleware
10
+ Middleware::Chain.new do |m|
11
+ end
12
+ end
13
+
14
+ def self.registered_workers
15
+ Sidekiq.redis { |x| x.smembers('workers') }
16
+ end
17
+
18
+ def self.registered_queues
19
+ Sidekiq.redis { |x| x.smembers('queues') }
20
+ end
21
+
22
+ ##
23
+ # The main method used to push a job to Redis. Accepts a number of options:
24
+ #
25
+ # queue - the named queue to use, default 'default'
26
+ # class - the worker class to call, required
27
+ # args - an array of simple arguments to the perform method, must be JSON-serializable
28
+ # retry - whether to retry this job if it fails, true or false, default true
29
+ # backtrace - whether to save any error backtrace, default false
30
+ #
31
+ # All options must be strings, not symbols. NB: because we are serializing to JSON, all
32
+ # symbols in 'args' will be converted to strings.
33
+ #
34
+ # Example:
35
+ # Sidekiq::Client.push('queue' => 'my_queue', 'class' => MyWorker, 'args' => ['foo', 1, :bat => 'bar'])
36
+ #
37
+ def self.push(item)
38
+ raise(ArgumentError, "Message must be a Hash of the form: { 'class' => SomeWorker, 'args' => ['bob', 1, :foo => 'bar'] }") unless item.is_a?(Hash)
39
+ raise(ArgumentError, "Message must include a class and set of arguments: #{item.inspect}") if !item['class'] || !item['args']
40
+ raise(ArgumentError, "Message must include a Sidekiq::Worker class, not class name: #{item['class'].ancestors.inspect}") if !item['class'].is_a?(Class) || !item['class'].respond_to?('get_sidekiq_options')
41
+
42
+ worker_class = item['class']
43
+ item['class'] = item['class'].to_s
44
+
45
+ item = worker_class.get_sidekiq_options.merge(item)
46
+ item['retry'] = !!item['retry']
47
+ queue = item['queue']
48
+
49
+ pushed = false
50
+ Sidekiq.client_middleware.invoke(worker_class, item, queue) do
51
+ payload = Sidekiq.dump_json(item)
52
+ Sidekiq.redis do |conn|
53
+ _, pushed = conn.multi do
54
+ conn.sadd('queues', queue)
55
+ conn.rpush("queue:#{queue}", payload)
56
+ end
57
+ end
58
+ end
59
+ !! pushed
60
+ end
61
+
62
+ # Redis compatibility helper. Example usage:
63
+ #
64
+ # Sidekiq::Client.enqueue(MyWorker, 'foo', 1, :bat => 'bar')
65
+ #
66
+ # Messages are enqueued to the 'default' queue.
67
+ #
68
+ def self.enqueue(klass, *args)
69
+ klass.perform_async(*args)
70
+ end
71
+ end
72
+ end