mirror of
https://github.com/mperham/sidekiq.git
synced 2022-11-09 13:52:34 -05:00
Rename workers to processors. New Railtie support.
Workers are the user's classes, the threads are now called processors. Add secret sauce to make Rails config much easier. Use a railtie to auto-add app/workers to the autoload path.
This commit is contained in:
parent
f08036f73e
commit
2771a0ad96
10 changed files with 100 additions and 47 deletions
|
@ -1,2 +1,4 @@
|
||||||
require 'sidekiq/version'
|
require 'sidekiq/version'
|
||||||
require 'sidekiq/client'
|
require 'sidekiq/client'
|
||||||
|
require 'sidekiq/worker'
|
||||||
|
require 'sidekiq/rails' if defined?(Rails)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
require 'optparse'
|
require 'optparse'
|
||||||
require 'sidekiq'
|
require 'sidekiq/version'
|
||||||
|
require 'sidekiq/util'
|
||||||
|
require 'sidekiq/client'
|
||||||
require 'sidekiq/server'
|
require 'sidekiq/server'
|
||||||
require 'connection_pool'
|
require 'connection_pool'
|
||||||
|
|
||||||
|
@ -34,7 +36,7 @@ module Sidekiq
|
||||||
def boot_rails
|
def boot_rails
|
||||||
ENV['RAILS_ENV'] = @options[:environment]
|
ENV['RAILS_ENV'] = @options[:environment]
|
||||||
require File.expand_path("#{@options[:rails]}/config/environment.rb")
|
require File.expand_path("#{@options[:rails]}/config/environment.rb")
|
||||||
Rails.application.eager_load!
|
::Rails.application.eager_load!
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate!
|
def validate!
|
||||||
|
@ -51,7 +53,7 @@ module Sidekiq
|
||||||
@options = {
|
@options = {
|
||||||
:verbose => false,
|
:verbose => false,
|
||||||
:queues => ['default'],
|
:queues => ['default'],
|
||||||
:worker_count => 25,
|
:processor_count => 25,
|
||||||
:server => 'redis://localhost:6379/0',
|
:server => 'redis://localhost:6379/0',
|
||||||
:rails => '.',
|
:rails => '.',
|
||||||
:environment => 'production',
|
:environment => 'production',
|
||||||
|
@ -77,12 +79,12 @@ module Sidekiq
|
||||||
@options[:environment] = arg
|
@options[:environment] = arg
|
||||||
end
|
end
|
||||||
|
|
||||||
o.on '-r', '--rails PATH', "Rails application with workers" do |arg|
|
o.on '-r', '--rails PATH', "Rails application with processors" do |arg|
|
||||||
@options[:rails] = arg
|
@options[:rails] = arg
|
||||||
end
|
end
|
||||||
|
|
||||||
o.on '-c', '--concurrency INT', "Worker threads to use" do |arg|
|
o.on '-c', '--concurrency INT', "processor threads to use" do |arg|
|
||||||
@options[:worker_count] = arg.to_i
|
@options[:processor_count] = arg.to_i
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
28
lib/sidekiq/processor.rb
Normal file
28
lib/sidekiq/processor.rb
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
require 'active_support/inflector'
|
||||||
|
|
||||||
|
module Sidekiq
|
||||||
|
class Processor
|
||||||
|
include Celluloid
|
||||||
|
|
||||||
|
def initialize(boss)
|
||||||
|
@boss = boss
|
||||||
|
end
|
||||||
|
|
||||||
|
def process(msg)
|
||||||
|
begin
|
||||||
|
klass = msg['class'].constantize
|
||||||
|
klass.new.perform(*msg['args'])
|
||||||
|
@boss.processor_done!(current_actor)
|
||||||
|
rescue => ex
|
||||||
|
send_to_airbrake(msg, ex) if defined?(::Airbrake)
|
||||||
|
raise ex
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_to_airbrake(msg, ex)
|
||||||
|
::Airbrake.notify(:error_class => ex.class.name,
|
||||||
|
:error_message => "#{ex.class.name}: #{e.message}",
|
||||||
|
:parameters => json)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
5
lib/sidekiq/rails.rb
Normal file
5
lib/sidekiq/rails.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
module Sidekiq
|
||||||
|
class Rails < ::Rails::Engine
|
||||||
|
config.autoload_paths << File.expand_path("#{config.root}/app/workers") if File.exist?("#{config.root}/app/workers")
|
||||||
|
end
|
||||||
|
end
|
|
@ -3,25 +3,25 @@ require 'redis'
|
||||||
require 'multi_json'
|
require 'multi_json'
|
||||||
|
|
||||||
require 'sidekiq/util'
|
require 'sidekiq/util'
|
||||||
require 'sidekiq/worker'
|
require 'sidekiq/processor'
|
||||||
|
|
||||||
module Sidekiq
|
module Sidekiq
|
||||||
|
|
||||||
##
|
##
|
||||||
# This is the main router in the system. This
|
# This is the main router in the system. This
|
||||||
# manages the worker state and fetches messages
|
# manages the processor state and fetches messages
|
||||||
# from Redis to be dispatched to ready workers.
|
# from Redis to be dispatched to ready processor.
|
||||||
#
|
#
|
||||||
class Server
|
class Server
|
||||||
include Util
|
include Util
|
||||||
include Celluloid
|
include Celluloid
|
||||||
|
|
||||||
trap_exit :worker_died
|
trap_exit :processor_died
|
||||||
|
|
||||||
def initialize(location, options={})
|
def initialize(location, options={})
|
||||||
log "Booting sidekiq #{Sidekiq::VERSION} with Redis at #{location}"
|
log "Booting sidekiq #{Sidekiq::VERSION} with Redis at #{location}"
|
||||||
verbose options.inspect
|
verbose options.inspect
|
||||||
@count = options[:worker_count]
|
@count = options[:processor_count]
|
||||||
@queues = options[:queues]
|
@queues = options[:queues]
|
||||||
@queue_idx = 0
|
@queue_idx = 0
|
||||||
@queues_size = @queues.size
|
@queues_size = @queues.size
|
||||||
|
@ -31,7 +31,7 @@ module Sidekiq
|
||||||
@busy = []
|
@busy = []
|
||||||
@ready = []
|
@ready = []
|
||||||
@count.times do
|
@count.times do
|
||||||
@ready << Worker.new_link(current_actor)
|
@ready << Processor.new_link(current_actor)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -49,26 +49,26 @@ module Sidekiq
|
||||||
dispatch(true)
|
dispatch(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
def worker_done(worker)
|
def processor_done(processor)
|
||||||
@busy.delete(worker)
|
@busy.delete(processor)
|
||||||
if stopped?
|
if stopped?
|
||||||
worker.terminate
|
processor.terminate
|
||||||
else
|
else
|
||||||
@ready << worker
|
@ready << processor
|
||||||
end
|
end
|
||||||
dispatch
|
dispatch
|
||||||
end
|
end
|
||||||
|
|
||||||
def worker_died(worker, reason)
|
def processor_died(processor, reason)
|
||||||
@busy.delete(worker)
|
@busy.delete(processor)
|
||||||
|
|
||||||
if reason
|
if reason
|
||||||
log "Worker death: #{reason}"
|
log "Processor death: #{reason}"
|
||||||
log reason.backtrace.join("\n")
|
log reason.backtrace.join("\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
unless stopped?
|
unless stopped?
|
||||||
@ready << Worker.new_link(current_actor)
|
@ready << Processor.new_link(current_actor)
|
||||||
dispatch
|
dispatch
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -79,9 +79,9 @@ module Sidekiq
|
||||||
current_queue = @queues[queue_idx]
|
current_queue = @queues[queue_idx]
|
||||||
msg = @redis.lpop("queue:#{current_queue}")
|
msg = @redis.lpop("queue:#{current_queue}")
|
||||||
if msg
|
if msg
|
||||||
worker = @ready.pop
|
processor = @ready.pop
|
||||||
@busy << worker
|
@busy << processor
|
||||||
worker.process! MultiJson.decode(msg)
|
processor.process! MultiJson.decode(msg)
|
||||||
end
|
end
|
||||||
msg
|
msg
|
||||||
end
|
end
|
||||||
|
@ -95,8 +95,8 @@ module Sidekiq
|
||||||
queue_idx = 0
|
queue_idx = 0
|
||||||
found = false
|
found = false
|
||||||
loop do
|
loop do
|
||||||
# return so that we don't dispatch again until worker_done
|
# return so that we don't dispatch again until processor_done
|
||||||
break verbose('no workers') if @ready.size == 0
|
break verbose('no processors') if @ready.size == 0
|
||||||
|
|
||||||
found ||= find_work(queue_idx)
|
found ||= find_work(queue_idx)
|
||||||
queue_idx += 1
|
queue_idx += 1
|
||||||
|
|
|
@ -1,28 +1,29 @@
|
||||||
require 'active_support/inflector'
|
require 'sidekiq/client'
|
||||||
|
|
||||||
module Sidekiq
|
module Sidekiq
|
||||||
class Worker
|
|
||||||
include Celluloid
|
|
||||||
|
|
||||||
def initialize(boss)
|
##
|
||||||
@boss = boss
|
# Include this module in your worker class and you can easily create
|
||||||
end
|
# asynchronous jobs:
|
||||||
|
#
|
||||||
|
# class HardWorker
|
||||||
|
# include Sidekiq::Worker
|
||||||
|
#
|
||||||
|
# def perform(*args)
|
||||||
|
# # do some work
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# Then in your Rails app, you can do this:
|
||||||
|
#
|
||||||
|
# HardWorker.perform_async(1, 2, 3)
|
||||||
|
#
|
||||||
|
# Note that perform_async is a class method, perform is an instance method.
|
||||||
|
module Worker
|
||||||
|
extend self
|
||||||
|
|
||||||
def process(msg)
|
def perform_async(*args)
|
||||||
begin
|
Sidekiq::Client.enqueue('class' => self.name, 'args' => args)
|
||||||
klass = msg['class'].constantize
|
|
||||||
klass.new.perform(*msg['args'])
|
|
||||||
@boss.worker_done!(current_actor)
|
|
||||||
rescue => ex
|
|
||||||
send_to_airbrake(msg, ex) if defined?(::Airbrake)
|
|
||||||
raise ex
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def send_to_airbrake(msg, ex)
|
|
||||||
::Airbrake.notify(:error_class => ex.class.name,
|
|
||||||
:error_message => "#{ex.class.name}: #{e.message}",
|
|
||||||
:parameters => json)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,3 +2,4 @@ source 'https://rubygems.org'
|
||||||
|
|
||||||
gem 'rails', '3.2.0'
|
gem 'rails', '3.2.0'
|
||||||
gem 'sqlite3'
|
gem 'sqlite3'
|
||||||
|
gem 'sidekiq', :path => '..'
|
||||||
|
|
|
@ -1,3 +1,12 @@
|
||||||
|
PATH
|
||||||
|
remote: ..
|
||||||
|
specs:
|
||||||
|
sidekiq (0.1.0)
|
||||||
|
celluloid
|
||||||
|
connection_pool
|
||||||
|
multi_json
|
||||||
|
redis
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
|
@ -30,6 +39,8 @@ GEM
|
||||||
multi_json (~> 1.0)
|
multi_json (~> 1.0)
|
||||||
arel (3.0.0)
|
arel (3.0.0)
|
||||||
builder (3.0.0)
|
builder (3.0.0)
|
||||||
|
celluloid (0.7.2)
|
||||||
|
connection_pool (0.1.0)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
hike (1.2.1)
|
hike (1.2.1)
|
||||||
i18n (0.6.0)
|
i18n (0.6.0)
|
||||||
|
@ -67,6 +78,7 @@ GEM
|
||||||
rake (0.9.2.2)
|
rake (0.9.2.2)
|
||||||
rdoc (3.12)
|
rdoc (3.12)
|
||||||
json (~> 1.4)
|
json (~> 1.4)
|
||||||
|
redis (2.2.2)
|
||||||
sprockets (2.1.2)
|
sprockets (2.1.2)
|
||||||
hike (~> 1.2)
|
hike (~> 1.2)
|
||||||
rack (~> 1.0)
|
rack (~> 1.0)
|
||||||
|
@ -84,4 +96,5 @@ PLATFORMS
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
rails (= 3.2.0)
|
rails (= 3.2.0)
|
||||||
|
sidekiq!
|
||||||
sqlite3
|
sqlite3
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
class HardWorker
|
class HardWorker
|
||||||
def perform(name, count)
|
def perform(name, count)
|
||||||
|
sleep 0.01
|
||||||
|
puts 'done'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,7 +17,6 @@ module Myapp
|
||||||
|
|
||||||
# Custom directories with classes and modules you want to be autoloadable.
|
# Custom directories with classes and modules you want to be autoloadable.
|
||||||
# config.autoload_paths += %W(#{config.root}/extras)
|
# config.autoload_paths += %W(#{config.root}/extras)
|
||||||
config.autoload_paths += %W(#{config.root}/app/workers)
|
|
||||||
|
|
||||||
# Only load the plugins named here, in the order given (default is alphabetical).
|
# Only load the plugins named here, in the order given (default is alphabetical).
|
||||||
# :all can be used as a placeholder for all plugins not explicitly named.
|
# :all can be used as a placeholder for all plugins not explicitly named.
|
||||||
|
|
Loading…
Add table
Reference in a new issue