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
		Add a link
		
	
		Reference in a new issue