Skip to content

Commit

Permalink
Allow users to explicitly specify the queue backend to use
Browse files Browse the repository at this point in the history
* Add a configuration block for the main module
* Make backend auto detection more specific
* Refactor the job dispatching logic
* Add some basic specs
* Update the README with usage info
* Rearrange autoload to the top of the main module
* Suppress warning output in specs
  • Loading branch information
Jay Zeschin committed Oct 15, 2012
1 parent 333365c commit 844c155
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 35 deletions.
9 changes: 9 additions & 0 deletions README.md
Expand Up @@ -33,6 +33,15 @@ gem 'carrierwave_backgrounder'

## Getting Started

In an initializer:

```ruby
CarrierWave::Backgrounder.configure do |c|
# :delayed_job, :girl_friday, :sidekiq, :qu, :resque, or :qc
c.backend = :delayed_job
end
```

In your CarrierWave uploader file:

```ruby
Expand Down
28 changes: 2 additions & 26 deletions lib/backgrounder/orm/base.rb
Expand Up @@ -50,19 +50,7 @@ def set_#{column}_processing
end
def enqueue_#{column}_background_job
if defined? ::GirlFriday
CARRIERWAVE_QUEUE << { :worker => #{worker}.new(self.class.name, id, #{column}.mounted_as) }
elsif defined? ::Delayed::Job
::Delayed::Job.enqueue #{worker}.new(self.class.name, id, #{column}.mounted_as)
elsif defined? ::Resque
::Resque.enqueue #{worker}, self.class.name, id, #{column}.mounted_as
elsif defined? ::Qu
::Qu.enqueue #{worker}, self.class.name, id, #{column}.mounted_as
elsif defined? ::Sidekiq
::Sidekiq::Client.enqueue #{worker}, self.class.name, id, #{column}.mounted_as
elsif defined? ::QC
::QC.enqueue "#{worker}.perform", self.class.name, id, #{column}.mounted_as.to_s
end
CarrierWave::Backgrounder.enqueue_for_backend(#{worker}, self.class.name, id, #{column}.mounted_as)
end
def trigger_#{column}_background_processing?
Expand Down Expand Up @@ -110,19 +98,7 @@ def store_#{column}!
end
def enqueue_#{column}_background_job
if defined? ::GirlFriday
CARRIERWAVE_QUEUE << { :worker => #{worker}.new(self.class.name, id, #{column}.mounted_as) }
elsif defined? ::Delayed::Job
::Delayed::Job.enqueue #{worker}.new(self.class.name, id, #{column}.mounted_as)
elsif defined? ::Resque
::Resque.enqueue #{worker}, self.class.name, id, #{column}.mounted_as
elsif defined? ::Qu
::Qu.enqueue #{worker}, self.class.name, id, #{column}.mounted_as
elsif defined? ::Sidekiq
::Sidekiq::Client.enqueue #{worker}, self.class.name, id, #{column}.mounted_as
elsif defined? ::QC
::QC.enqueue "#{worker}.perform", self.class.name, id, #{column}.mounted_as.to_s
end
CarrierWave::Backgrounder.enqueue_for_backend(#{worker}, self.class.name, id, #{column}.mounted_as)
end
def trigger_#{column}_background_storage?
Expand Down
73 changes: 65 additions & 8 deletions lib/carrierwave_backgrounder.rb
@@ -1,5 +1,6 @@
module CarrierWave
module Backgrounder

Logger = Logger.new(STDOUT)

autoload :Delay, 'backgrounder/delay'
Expand All @@ -8,6 +9,70 @@ module Backgrounder
module ORM
autoload :Base, 'backgrounder/orm/base'
end

class << self
def backend=(value)
@backend = value
self.configure_backend
end

def backend
return @backend unless @backend.nil?
if available_backends.empty?
warn 'WARNING: No queue backends found to use for CarrierWave::Backgrounder'
elsif available_backends.size == 1
self.backend = available_backends.first
elsif available_backends.size > 1
warn 'WARNING: Multiple queue backends found for CarrierWave::Backgrounder. You need to set one explicitly.'
end
end

def configure
yield self
end

def available_backends
@available_backends ||= begin
backends = []
backends << :girl_friday if defined? ::GirlFriday
backends << :delayed_job if defined? ::Delayed::Job
backends << :resque if defined? ::Resque
backends << :qu if defined? ::Qu
backends << :sidekiq if defined? ::Sidekiq
backends << :qc if defined? ::QC
backends
end
end

def configure_backend
if backend == :girl_friday
require 'girl_friday'
@girl_friday_queue = GirlFriday::WorkQueue.new(:carrierwave) do |msg|
worker = msg[:worker]
worker.perform
end
end
end

def enqueue_for_backend(worker, class_name, subject_id, mounted_as)
case backend
when :girl_friday
@girl_friday_queue << { :worker => worker.new(self.class.name, subject_id, mounted_as) }
when :delayed_job
::Delayed::Job.enqueue worker.new(class_name, subject_id, mounted_as)
when :resque
::Resque.enqueue worker, class_name, subject_id, mounted_as
when :qu
::Qu.enqueue worker, class_name, subject_id, column.mounted_as
when :sidekiq
::Sidekiq::Client.enqueue worker, class_name, subject_id, mounted_as
when :qc
::QC.enqueue "#{worker.name}.perform", class_name, subject_id, mounted_as.to_s
end
end

end

end
end

Expand Down Expand Up @@ -35,11 +100,3 @@ class Railtie < Rails::Railtie
end
end

if defined?(GirlFriday)
require 'girl_friday'

CARRIERWAVE_QUEUE = GirlFriday::WorkQueue.new(:carrierwave) do |msg|
worker = msg[:worker]
worker.perform
end
end
67 changes: 67 additions & 0 deletions spec/backgrounder/backends_spec.rb
@@ -0,0 +1,67 @@
require 'spec_helper'
require 'carrierwave_backgrounder'

describe CarrierWave::Backgrounder do

describe 'enumerating available backends' do

it 'detects GirlFriday' do
CarrierWave::Backgrounder.available_backends.should include(:girl_friday)
end
it 'detects Delayed::Job' do
CarrierWave::Backgrounder.available_backends.should include(:delayed_job)
end
it 'detects Resque' do
CarrierWave::Backgrounder.available_backends.should include(:resque)
end
it 'detects Qu' do
CarrierWave::Backgrounder.available_backends.should include(:qu)
end
it 'detects Sidekiq' do
CarrierWave::Backgrounder.available_backends.should include(:sidekiq)
end
it 'detects QC' do
CarrierWave::Backgrounder.available_backends.should include(:qc)
end
end

describe 'automatically setting backends' do

before do
CarrierWave::Backgrounder.instance_variable_set('@backend', nil)
end

it 'does not set a backend if none are available' do
suppress_warnings do
CarrierWave::Backgrounder.stubs(:available_backends).returns([])
CarrierWave::Backgrounder.backend.should be_nil
end
end
it 'sets a backend automatically if only one is available' do
CarrierWave::Backgrounder.stubs(:available_backends).returns([ :qu ])
CarrierWave::Backgrounder.backend.should eq(:qu)
end
it 'does not set a backend if more than one is available' do
suppress_warnings do
CarrierWave::Backgrounder.stubs(:available_backends).returns([:qu, :resque])
CarrierWave::Backgrounder.backend.should be_nil
end
end

it 'does not clobber a manually set backend' do
CarrierWave::Backgrounder.backend = :not_a_backend
CarrierWave::Backgrounder.backend.should eq(:not_a_backend)
end

it 'calls configure_backend when setting the backend' do
CarrierWave::Backgrounder.stubs(:available_backends).returns([ :qu ])
CarrierWave::Backgrounder.expects(:configure_backend).once
CarrierWave::Backgrounder.backend.should eq(:qu)
end

end



end

16 changes: 15 additions & 1 deletion spec/spec_helper.rb
@@ -1,7 +1,21 @@
# encoding: utf-8
require 'rubygems'
require 'bundler/setup'
require 'support/backend_constants'
require 'logger'

module WarningSuppression
def suppress_warnings
original_verbosity = $VERBOSE
$VERBOSE = nil
result = yield
$VERBOSE = original_verbosity
return result
end
end

RSpec.configure do |c|
c.mock_with :mocha
end
c.include WarningSuppression
end

23 changes: 23 additions & 0 deletions spec/support/backend_constants.rb
@@ -0,0 +1,23 @@
# Fixture module declarations for backend detection testing

module GirlFriday
end

module Delayed
module Job
end
end

module Resque
end

module Qu
end

module Sidekiq
module Worker
end
end

module QC
end

0 comments on commit 844c155

Please sign in to comment.