kulesa-sidekiq 1.2.2

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