carrierwave_backgrounder 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,78 +1,95 @@
1
- = CarrierWave Backgrounder
1
+ # CarrierWave Backgrounder
2
2
 
3
- I like CarrierWave. That being said, I don't like tying up app instances waiting for images to process. This gem addresses that issue.
3
+ I like CarrierWave. That being said, I don't like tying up app instances waiting for images to process.
4
+
5
+ This gem addresses that issue by disabling processing until a background process initiates it.
6
+ It supports both Delayed Job and Resque.
7
+
8
+ ## Background options
4
9
 
5
- == Background options
6
-
7
10
  There are currently two offerings for backgrounding upload tasks which are as follows;
8
11
 
9
- Backgrounder::ORM::Base::process_in_background
12
+ ```ruby
13
+ Backgrounder::ORM::Base::process_in_background
14
+ ```
10
15
 
11
16
  This method stores the original file and does no processing or versioning. Optionally you can add a column to the database which will be set to nil when the background processing is complete.
12
-
13
- Backgrounder::ORM::Base::store_in_background
14
-
17
+
18
+ ```ruby
19
+ Backgrounder::ORM::Base::store_in_background
20
+ ```
21
+
15
22
  This method does nothing to the file after it is cached which makes it super fast. It requires a column in the database which stores the cache location set by carrierwave. The drawback to using this method is the need for a central location to store the cached files. This leave heroku out. Heroku may deploy workers on separate servers from where your dyno cached the files. That being said, I only recommend using this method if you have full control over your temp storage directory.
16
23
 
17
- == Installation
24
+ ## Installation
18
25
 
19
- These instructions assume you have previously set up {CarrierWave}[https://github.com/jnicklas/carrierwave] and {DelayedJob}[https://github.com/collectiveidea/delayed_job]
26
+ These instructions assume you have previously set up [CarrierWave](https://github.com/jnicklas/carrierwave) and [DelayedJob](https://github.com/collectiveidea/delayed_job) or Resque
20
27
 
21
28
  In Rails, add the following your Gemfile:
22
-
23
- gem 'carrierwave_backgrounder'
24
-
25
- == Getting Started
26
29
 
27
- === To use process_in_background
28
-
30
+ ```ruby
31
+ gem 'carrierwave_backgrounder'
32
+ ```
33
+
34
+ ## Getting Started
35
+
36
+ ### To use process_in_background
37
+
29
38
  In your model:
30
-
31
- mount_uploader :avatar, AvatarUploader
32
- process_in_background :avatar
33
-
34
- === To use store_in_background
35
-
39
+
40
+ ```ruby
41
+ mount_uploader :avatar, AvatarUploader
42
+ process_in_background :avatar
43
+ ```
44
+
45
+ ### To use store_in_background
46
+
36
47
  In your model:
37
48
 
38
- mount_uploader :avatar, AvatarUploader
39
- process_in_background :avatar
49
+ ```ruby
50
+ mount_uploader :avatar, AvatarUploader
51
+ store_in_background :avatar
52
+ ```
40
53
 
41
54
  Add a column to the model you want to background which will store the temp file location:
42
55
 
43
- add_column :users, :avatar_tmp, :string
56
+ ```ruby
57
+ add_column :users, :avatar_tmp, :string
58
+ ```
44
59
 
45
60
  In your CarrierWave uploader file:
46
61
 
47
- class AvatarUploader < CarrierWave::Uploader::Base
48
- include ::CarrierWave::Backgrounder::DelayStorage
62
+ ```ruby
63
+ class AvatarUploader < CarrierWave::Uploader::Base
64
+ include ::CarrierWave::Backgrounder::DelayStorage
49
65
 
50
- #ect...
51
- end
66
+ #ect...
67
+ end
68
+ ```
52
69
 
53
- == Usage Tips
70
+ ## Usage Tips
54
71
 
55
72
  If you need to process/store the upload immediately:
56
73
 
57
- @user.process_<column>_upload = true
58
-
59
- == ORM
74
+ ```ruby
75
+ @user.process_<column>_upload = true
76
+ ```
60
77
 
61
- Currently ActiveRecord is the default orm and I have not tested this with others but it should work by adding the following to your carrierwave initializer:
78
+ ## ORM
62
79
 
63
- DataMapper::Model.send(:include, ::CarrierWave::Backgrounder::ORM::Base)
64
- # or
65
- Mongoid::Document::ClassMethods.send(:include, ::CarrierWave::Backgrounder::ORM::Base)
66
- # or
67
- Sequel::Model.send(:extend, ::CarrierWave::Backgrounder::ORM::Base)
68
-
69
- Contributions are gladly accepted from those who use these orms.
80
+ Currently ActiveRecord is the default orm and I have not tested this with others but it should work by adding the following to your carrierwave initializer:
70
81
 
71
- == TODO
82
+ ```ruby
83
+ DataMapper::Model.send(:include, ::CarrierWave::Backgrounder::ORM::Base)
84
+ # or
85
+ Mongoid::Document::ClassMethods.send(:include, ::CarrierWave::Backgrounder::ORM::Base)
86
+ # or
87
+ Sequel::Model.send(:extend, ::CarrierWave::Backgrounder::ORM::Base)
88
+ ```
72
89
 
73
- More specs
90
+ Contributions are gladly accepted from those who use these orms.
74
91
 
75
- == License
92
+ ## License
76
93
 
77
94
  Copyright (c) 2011 Larry Sprock
78
95
 
@@ -93,4 +110,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
93
110
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
94
111
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
95
112
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
96
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
113
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -2,14 +2,23 @@ module CarrierWave
2
2
  module Backgrounder
3
3
 
4
4
  module DelayStorage
5
+
6
+ ##
7
+ #Intercept carrierwave#cache_versions! so we can process versions later.
5
8
  def cache_versions!(new_file)
6
9
  super(new_file) if proceed_with_versioning?
7
10
  end
8
11
 
12
+ def process!(new_file=nil)
13
+ super(new_file) if proceed_with_versioning?
14
+ end
15
+
16
+ private
17
+
9
18
  def proceed_with_versioning?
10
19
  !model.respond_to?(:"process_#{mounted_as}_upload") || model.send(:"process_#{mounted_as}_upload")
11
20
  end
12
21
  end # DelayStorage
13
22
 
14
23
  end # Backgrounder
15
- end # CarrierWave
24
+ end # CarrierWave
@@ -50,7 +50,15 @@ module CarrierWave
50
50
  end
51
51
 
52
52
  def enqueue_#{column}_background_job
53
- ::Delayed::Job.enqueue #{worker}.new(self.class, id, #{column}.mounted_as)
53
+ if defined? ::GirlFriday
54
+ CARRIERWAVE_QUEUE << { :worker => #{worker}.new(self.class.name, id, #{column}.mounted_as) }
55
+ elsif defined? ::Delayed::Job
56
+ ::Delayed::Job.enqueue #{worker}.new(self.class.name, id, #{column}.mounted_as)
57
+ elsif defined? ::Resque
58
+ ::Resque.enqueue #{worker}, self.class.name, id, #{column}.mounted_as
59
+ elsif defined? ::Qu
60
+ ::Qu.enqueue #{worker}, self.class.name, id, #{column}.mounted_as
61
+ end
54
62
  end
55
63
 
56
64
  def trigger_#{column}_background_processing?
@@ -98,7 +106,15 @@ module CarrierWave
98
106
  end
99
107
 
100
108
  def enqueue_#{column}_background_job
101
- ::Delayed::Job.enqueue #{worker}.new(self.class, id, #{column}.mounted_as)
109
+ if defined? ::GirlFriday
110
+ CARRIERWAVE_QUEUE << { :worker => #{worker}.new(self.class.name, id, #{column}.mounted_as) }
111
+ elsif defined? ::Delayed::Job
112
+ ::Delayed::Job.enqueue #{worker}.new(self.class.name, id, #{column}.mounted_as)
113
+ elsif defined? ::Resque
114
+ ::Resque.enqueue #{worker}, self.class.name, id, #{column}.mounted_as
115
+ elsif defined? ::Qu
116
+ ::Qu.enqueue #{worker}, self.class.name, id, #{column}.mounted_as
117
+ end
102
118
  end
103
119
 
104
120
  def trigger_#{column}_background_storage?
@@ -1,5 +1,5 @@
1
1
  module CarrierWave
2
2
  module Backgrounder
3
- VERSION = "0.0.5"
3
+ VERSION = "0.0.6"
4
4
  end
5
5
  end
@@ -3,9 +3,15 @@ module CarrierWave
3
3
  module Workers
4
4
 
5
5
  class ProcessAsset < Struct.new(:klass, :id, :column)
6
-
6
+ @queue = :process_asset
7
+
8
+ def self.perform(*args)
9
+ new(*args).perform
10
+ end
11
+
7
12
  def perform
8
- record = klass.find id
13
+ resource = klass.is_a?(String) ? klass.constantize : klass
14
+ record = resource.find id
9
15
  record.send(:"process_#{column}_upload=", true)
10
16
  if record.send(:"#{column}").recreate_versions! && record.respond_to?(:"#{column}_processing")
11
17
  record.update_attribute :"#{column}_processing", nil
@@ -3,19 +3,25 @@ module CarrierWave
3
3
  module Workers
4
4
 
5
5
  class StoreAsset < Struct.new(:klass, :id, :column)
6
-
6
+ @queue = :store_asset
7
+
8
+ def self.perform(*args)
9
+ new(*args).perform
10
+ end
11
+
7
12
  def perform
8
- record = klass.find id
13
+ resource = klass.is_a?(String) ? klass.constantize : klass
14
+ record = resource.find id
9
15
  if tmp = record.send(:"#{column}_tmp")
10
16
  asset = record.send(:"#{column}")
11
17
  cache_dir = [asset.root, asset.cache_dir].join("/")
12
18
  cache_path = [cache_dir, tmp].join("/")
13
-
19
+ tmp_dir = [cache_dir, tmp.split("/")[0]].join("/")
14
20
  record.send :"process_#{column}_upload=", true
15
21
  record.send :"#{column}_tmp=", nil
16
22
  File.open(cache_path) { |f| record.send :"#{column}=", f }
17
23
  if record.save!
18
- FileUtils.rm(cache_path)
24
+ FileUtils.rm_r(tmp_dir, :force => true)
19
25
  end
20
26
  end
21
27
  end
@@ -21,3 +21,12 @@ if defined?(Rails)
21
21
  end
22
22
  end
23
23
  end
24
+
25
+ if defined?(GirlFriday)
26
+ require 'girl_friday'
27
+
28
+ CARRIERWAVE_QUEUE = GirlFriday::WorkQueue.new(:carrierwave) do |msg|
29
+ worker = msg[:worker]
30
+ worker.perform
31
+ end
32
+ end
File without changes
@@ -2,24 +2,33 @@
2
2
  require 'spec_helper'
3
3
  require 'backgrounder/workers/process_asset'
4
4
 
5
- describe worker = CarrierWave::Workers::ProcessAsset do
6
- before do
7
- @user = mock('User')
8
- @image = mock('UserAsset')
9
- @worker = worker.new(@user, '22', :image)
5
+ describe CarrierWave::Workers::ProcessAsset do
6
+ let(:worker_class) { CarrierWave::Workers::ProcessAsset }
7
+ let(:user) { mock('User') }
8
+ let(:image) { mock('UserAsset') }
9
+ let!(:worker) { worker_class.new(user, '22', :image) }
10
+
11
+ context ".perform" do
12
+ it 'creates a new instance and calls perform' do
13
+ args = [user, '22', :image]
14
+ worker_class.expects(:new).with(*args).returns(worker)
15
+ worker_class.any_instance.expects(:perform)
16
+
17
+ worker_class.perform(*args)
18
+ end
10
19
  end
11
20
 
12
21
  context "#perform" do
13
22
  it 'processes versions' do
14
- @user.expects(:find).with('22').returns(@user).once
15
- @user.expects(:image).once.returns(@image)
16
- @user.expects(:process_image_upload=).with(true).once
23
+ user.expects(:find).with('22').returns(user).once
24
+ user.expects(:image).once.returns(image)
25
+ user.expects(:process_image_upload=).with(true).once
17
26
 
18
- @image.expects(:recreate_versions!).once.returns(true)
19
- @user.expects(:respond_to?).with(:image_processing).once.returns(true)
20
- @user.expects(:update_attribute).with(:image_processing, nil).once
27
+ image.expects(:recreate_versions!).once.returns(true)
28
+ user.expects(:respond_to?).with(:image_processing).once.returns(true)
29
+ user.expects(:update_attribute).with(:image_processing, nil).once
21
30
 
22
- @worker.perform
31
+ worker.perform
23
32
  end
24
33
  end
25
34
  end
@@ -2,28 +2,36 @@
2
2
  require 'spec_helper'
3
3
  require 'backgrounder/workers/store_asset'
4
4
 
5
- describe worker = CarrierWave::Workers::StoreAsset do
6
- before do
7
- @user = mock('User')
8
- @image = mock('UserAsset')
9
- @worker = worker.new(@user, '22', :image)
5
+ describe CarrierWave::Workers::StoreAsset do
6
+ let(:worker_class) { CarrierWave::Workers::StoreAsset }
7
+ let(:user) { mock('User') }
8
+ let(:image) { mock('UserAsset') }
9
+ let!(:worker) { worker_class.new(user, '22', :image) }
10
+
11
+ context ".perform" do
12
+ it 'creates a new instance and calls perform' do
13
+ args = [user, '22', :image]
14
+ worker_class.expects(:new).with(*args).returns(worker)
15
+ worker_class.any_instance.expects(:perform)
16
+
17
+ worker_class.perform(*args)
18
+ end
10
19
  end
11
20
 
12
21
  context "#perform" do
13
22
  it 'processes versions' do
14
- File.expects(:open).with('../fixtures/test.jpg').once.returns('apple')
15
- FileUtils.expects(:rm).with('../fixtures/test.jpg').once
16
- @user.expects(:find).with('22').once.returns(@user)
17
- @user.expects(:image_tmp).once.returns('test.jpg')
18
- @user.expects(:image).once.returns(@image)
19
- @image.expects(:root).once.returns('..')
20
- @image.expects(:cache_dir).once.returns('fixtures')
21
- @user.expects(:process_image_upload=).with(true).once
22
- @user.expects(:image=).with('apple').once
23
- @user.expects(:image_tmp=).with(nil).once
24
- @user.expects(:save!).once.returns(true)
23
+ FileUtils.expects(:rm_r).with(File.expand_path('../fixtures/test.jpg', __FILE__),:force=>true).once
24
+ user.expects(:find).with('22').once.returns(user)
25
+ user.expects(:image_tmp).once.returns('test.jpg')
26
+ user.expects(:image).once.returns(image)
27
+ image.expects(:root).once.returns(File.expand_path('..', __FILE__))
28
+ image.expects(:cache_dir).once.returns('fixtures')
29
+ user.expects(:process_image_upload=).with(true).once
30
+ user.expects(:image=).once
31
+ user.expects(:image_tmp=).with(nil).once
32
+ user.expects(:save!).once.returns(true)
25
33
 
26
- @worker.perform
34
+ worker.perform
27
35
  end
28
36
  end
29
- end
37
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: carrierwave_backgrounder
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.5
5
+ version: 0.0.6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Larry Sprock
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-08-29 00:00:00 -07:00
13
+ date: 2011-12-07 00:00:00 -08:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -59,7 +59,7 @@ files:
59
59
  - .gitignore
60
60
  - .rspec
61
61
  - Gemfile
62
- - README.rdoc
62
+ - README.md
63
63
  - Rakefile
64
64
  - carrierwave_backgrounder.gemspec
65
65
  - lib/backgrounder/delay_storage.rb
@@ -71,6 +71,7 @@ files:
71
71
  - lib/backgrounder/workers/store_asset.rb
72
72
  - lib/carrierwave_backgrounder.rb
73
73
  - spec/spec_helper.rb
74
+ - spec/workers/fixtures/test.jpg
74
75
  - spec/workers/process_asset_spec.rb
75
76
  - spec/workers/store_asset_spec.rb
76
77
  has_rdoc: true
@@ -103,5 +104,6 @@ specification_version: 3
103
104
  summary: Offload CarrierWave's image processing and storage to a background process using Delayed Job
104
105
  test_files:
105
106
  - spec/spec_helper.rb
107
+ - spec/workers/fixtures/test.jpg
106
108
  - spec/workers/process_asset_spec.rb
107
109
  - spec/workers/store_asset_spec.rb