From 51b40035a91c1fff21aa7972d59c26f5f68f7c0e Mon Sep 17 00:00:00 2001 From: Piotr Kaczmarek Date: Sun, 12 Jul 2015 19:40:54 +0200 Subject: [PATCH] Add ActiveJob support --- README.md | 27 ++++++++++++ lib/backgrounder/support/backends.rb | 4 ++ lib/backgrounder/workers.rb | 3 ++ lib/backgrounder/workers/base.rb | 22 +++++++--- lib/backgrounder/workers/class_methods.rb | 14 ++++++ lib/backgrounder/workers/process_asset.rb | 15 +------ .../workers/process_asset_mixin.rb | 28 ++++++++++++ lib/backgrounder/workers/store_asset.rb | 28 +----------- lib/backgrounder/workers/store_asset_mixin.rb | 43 +++++++++++++++++++ .../initializers/carrierwave_backgrounder.rb | 1 + spec/backgrounder/support/backends_spec.rb | 10 +++++ 11 files changed, 149 insertions(+), 46 deletions(-) create mode 100644 lib/backgrounder/workers/class_methods.rb create mode 100644 lib/backgrounder/workers/process_asset_mixin.rb create mode 100644 lib/backgrounder/workers/store_asset_mixin.rb diff --git a/README.md b/README.md index f6e02d40..16da3337 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,33 @@ class MyParanoidWorker < ::CarrierWave::Workers::ProcessAsset # other hooks you might care about end ``` + +### ActiveJob +Use overriden worker that inherits from ActiveJob::Base and includes relevant worker mixin: +```ruby +class MyActiveJobWorker < ActiveJob::Base + include ::CarrierWave::Workers::ProcessAssetMixin + # ... or include ::CarrierWave::Workers::StoreAssetMixin + + after_perform do + # your code here + end + + # Sometimes job gets performed before the file is uploaded and ready. + # You can define how to handle that case by overriding `when_not_ready` method + # (by default it does nothing) + def when_not_ready + retry_job + end +end +``` +Don't forget to set `active_job` as a backend in the config: +```ruby +CarrierWave::Backgrounder.configure do |c| + c.backend :active_job, queue: :carrierwave +end +``` + ### Testing with Rspec We use the after_commit hook when using active_record. This creates a problem when testing with Rspec because after_commit never gets fired if you're using trasactional fixtures. One solution to the problem is to use the [TestAfterCommit gem](https://github.com/grosser/test_after_commit). diff --git a/lib/backgrounder/support/backends.rb b/lib/backgrounder/support/backends.rb index e59a4af3..168de319 100644 --- a/lib/backgrounder/support/backends.rb +++ b/lib/backgrounder/support/backends.rb @@ -22,6 +22,10 @@ def enqueue_for_backend(worker, class_name, subject_id, mounted_as) private + def enqueue_active_job(worker, *args) + worker.perform_later(*args.map(&:to_s)) + end + def enqueue_delayed_job(worker, *args) worker_args = {} if ::Delayed::Job.new.respond_to?(:queue) diff --git a/lib/backgrounder/workers.rb b/lib/backgrounder/workers.rb index 3adb99f1..05753d77 100644 --- a/lib/backgrounder/workers.rb +++ b/lib/backgrounder/workers.rb @@ -1,3 +1,6 @@ require 'backgrounder/workers/base' +require 'backgrounder/workers/class_methods' +require 'backgrounder/workers/process_asset_mixin' +require 'backgrounder/workers/store_asset_mixin' require 'backgrounder/workers/process_asset' require 'backgrounder/workers/store_asset' diff --git a/lib/backgrounder/workers/base.rb b/lib/backgrounder/workers/base.rb index cadba7fb..967c370e 100644 --- a/lib/backgrounder/workers/base.rb +++ b/lib/backgrounder/workers/base.rb @@ -1,14 +1,18 @@ +# encoding: utf-8 module CarrierWave module Workers - class Base < Struct.new(:klass, :id, :column) - def self.perform(*args) - new(*args).perform + module Base + attr_accessor :klass, :id, :column, :record + + def initialize(*args) + super(*args) unless self.class.superclass == Object + set_args(*args) if args.present? end def perform(*args) set_args(*args) if args.present? - constantized_resource.find id + self.record = constantized_resource.find id rescue *not_found_errors end @@ -29,6 +33,10 @@ def constantized_resource klass.is_a?(String) ? klass.constantize : klass end - end - end -end + def when_not_ready + end + + end # Base + + end # Workers +end # CarrierWave diff --git a/lib/backgrounder/workers/class_methods.rb b/lib/backgrounder/workers/class_methods.rb new file mode 100644 index 00000000..309599f5 --- /dev/null +++ b/lib/backgrounder/workers/class_methods.rb @@ -0,0 +1,14 @@ +# encoding: utf-8 +module CarrierWave + module Workers + + module ClassMethods + + def perform(*args) + new(*args).perform + end + + end # ClassMethods + + end # Workers +end # Backgrounder diff --git a/lib/backgrounder/workers/process_asset.rb b/lib/backgrounder/workers/process_asset.rb index df988d26..e1833ced 100644 --- a/lib/backgrounder/workers/process_asset.rb +++ b/lib/backgrounder/workers/process_asset.rb @@ -2,19 +2,8 @@ module CarrierWave module Workers - class ProcessAsset < Base - - def perform(*args) - record = super(*args) - - if record && record.send(:"#{column}").present? - record.send(:"process_#{column}_upload=", true) - if record.send(:"#{column}").recreate_versions! && record.respond_to?(:"#{column}_processing") - record.update_attribute :"#{column}_processing", false - end - end - end - + class ProcessAsset + include CarrierWave::Workers::ProcessAssetMixin end # ProcessAsset end # Workers diff --git a/lib/backgrounder/workers/process_asset_mixin.rb b/lib/backgrounder/workers/process_asset_mixin.rb new file mode 100644 index 00000000..dd14f1b2 --- /dev/null +++ b/lib/backgrounder/workers/process_asset_mixin.rb @@ -0,0 +1,28 @@ +# encoding: utf-8 +module CarrierWave + module Workers + + module ProcessAssetMixin + include CarrierWave::Workers::Base + + def self.included(base) + base.extend CarrierWave::Workers::ClassMethods + end + + def perform(*args) + record = super(*args) + + if record && record.send(:"#{column}").present? + record.send(:"process_#{column}_upload=", true) + if record.send(:"#{column}").recreate_versions! && record.respond_to?(:"#{column}_processing") + record.update_attribute :"#{column}_processing", false + end + else + when_not_ready + end + end + + end # ProcessAssetMixin + + end # Workers +end # Backgrounder diff --git a/lib/backgrounder/workers/store_asset.rb b/lib/backgrounder/workers/store_asset.rb index df93b8fd..4f45e3c5 100644 --- a/lib/backgrounder/workers/store_asset.rb +++ b/lib/backgrounder/workers/store_asset.rb @@ -2,32 +2,8 @@ module CarrierWave module Workers - class StoreAsset < Base - attr_reader :cache_path, :tmp_directory - - def perform(*args) - record = super(*args) - - if record && record.send(:"#{column}_tmp") - store_directories(record) - record.send :"process_#{column}_upload=", true - record.send :"#{column}_tmp=", nil - record.send :"#{column}_processing=", false if record.respond_to?(:"#{column}_processing") - File.open(cache_path) { |f| record.send :"#{column}=", f } - if record.save! - FileUtils.rm_r(tmp_directory, :force => true) - end - end - end - - private - - def store_directories(record) - asset, asset_tmp = record.send(:"#{column}"), record.send(:"#{column}_tmp") - cache_directory = File.expand_path(asset.cache_dir, asset.root) - @cache_path = File.join(cache_directory, asset_tmp) - @tmp_directory = File.join(cache_directory, asset_tmp.split("/").first) - end + class StoreAsset + include CarrierWave::Workers::StoreAssetMixin end # StoreAsset end # Workers diff --git a/lib/backgrounder/workers/store_asset_mixin.rb b/lib/backgrounder/workers/store_asset_mixin.rb new file mode 100644 index 00000000..1a151861 --- /dev/null +++ b/lib/backgrounder/workers/store_asset_mixin.rb @@ -0,0 +1,43 @@ +# encoding: utf-8 +module CarrierWave + module Workers + + module StoreAssetMixin + include CarrierWave::Workers::Base + + def self.included(base) + base.extend CarrierWave::Workers::ClassMethods + end + + attr_reader :cache_path, :tmp_directory + + def perform(*args) + record = super(*args) + + if record && record.send(:"#{column}_tmp") + store_directories(record) + record.send :"process_#{column}_upload=", true + record.send :"#{column}_tmp=", nil + record.send :"#{column}_processing=", false if record.respond_to?(:"#{column}_processing") + File.open(cache_path) { |f| record.send :"#{column}=", f } + if record.save! + FileUtils.rm_r(tmp_directory, :force => true) + end + else + when_not_ready + end + end + + private + + def store_directories(record) + asset, asset_tmp = record.send(:"#{column}"), record.send(:"#{column}_tmp") + cache_directory = File.expand_path(asset.cache_dir, asset.root) + @cache_path = File.join(cache_directory, asset_tmp) + @tmp_directory = File.join(cache_directory, asset_tmp.split("/").first) + end + + end # StoreAssetMixin + + end # Workers +end # Backgrounder diff --git a/lib/generators/carrierwave_backgrounder/templates/config/initializers/carrierwave_backgrounder.rb b/lib/generators/carrierwave_backgrounder/templates/config/initializers/carrierwave_backgrounder.rb index 9b1577fa..7350edd9 100644 --- a/lib/generators/carrierwave_backgrounder/templates/config/initializers/carrierwave_backgrounder.rb +++ b/lib/generators/carrierwave_backgrounder/templates/config/initializers/carrierwave_backgrounder.rb @@ -1,5 +1,6 @@ CarrierWave::Backgrounder.configure do |c| c.backend :delayed_job, queue: :carrierwave + # c.backend :active_job, queue: :carrierwave # c.backend :resque, queue: :carrierwave # c.backend :sidekiq, queue: :carrierwave # c.backend :girl_friday, queue: :carrierwave diff --git a/spec/backgrounder/support/backends_spec.rb b/spec/backgrounder/support/backends_spec.rb index 5e40e77c..64e5ce59 100644 --- a/spec/backgrounder/support/backends_spec.rb +++ b/spec/backgrounder/support/backends_spec.rb @@ -31,6 +31,16 @@ module CarrierWave::Backgrounder describe '#enqueue_for_backend' do let!(:worker) { MockWorker.new('FakeClass', 1, :image) } + context 'active_job' do + let(:args) { ['FakeClass', 1, :image] } + + it 'invokes perform_later with string arguments' do + expect(MockWorker).to receive(:perform_later).with('FakeClass', '1', 'image') + mock_module.backend :active_job + mock_module.enqueue_for_backend(MockWorker, *args) + end + end + context 'delayed_job' do before do @mock_worker = Class.new do