carrierwave_backgrounder 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/{README.rdoc → README.md} +62 -45
- data/lib/backgrounder/delay_storage.rb +10 -1
- data/lib/backgrounder/orm/base.rb +18 -2
- data/lib/backgrounder/version.rb +1 -1
- data/lib/backgrounder/workers/process_asset.rb +8 -2
- data/lib/backgrounder/workers/store_asset.rb +10 -4
- data/lib/carrierwave_backgrounder.rb +9 -0
- data/spec/workers/fixtures/test.jpg +0 -0
- data/spec/workers/process_asset_spec.rb +21 -12
- data/spec/workers/store_asset_spec.rb +26 -18
- metadata +5 -3
data/{README.rdoc → README.md}
RENAMED
@@ -1,78 +1,95 @@
|
|
1
|
-
|
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.
|
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
|
-
|
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
|
-
|
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
|
-
|
24
|
+
## Installation
|
18
25
|
|
19
|
-
These instructions assume you have previously set up
|
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
|
-
|
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
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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
|
-
|
39
|
-
|
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
|
-
|
56
|
+
```ruby
|
57
|
+
add_column :users, :avatar_tmp, :string
|
58
|
+
```
|
44
59
|
|
45
60
|
In your CarrierWave uploader file:
|
46
61
|
|
47
|
-
|
48
|
-
|
62
|
+
```ruby
|
63
|
+
class AvatarUploader < CarrierWave::Uploader::Base
|
64
|
+
include ::CarrierWave::Backgrounder::DelayStorage
|
49
65
|
|
50
|
-
|
51
|
-
|
66
|
+
#ect...
|
67
|
+
end
|
68
|
+
```
|
52
69
|
|
53
|
-
|
70
|
+
## Usage Tips
|
54
71
|
|
55
72
|
If you need to process/store the upload immediately:
|
56
73
|
|
57
|
-
|
58
|
-
|
59
|
-
|
74
|
+
```ruby
|
75
|
+
@user.process_<column>_upload = true
|
76
|
+
```
|
60
77
|
|
61
|
-
|
78
|
+
## ORM
|
62
79
|
|
63
|
-
|
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
|
-
|
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
|
-
|
90
|
+
Contributions are gladly accepted from those who use these orms.
|
74
91
|
|
75
|
-
|
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
|
-
|
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
|
-
|
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?
|
data/lib/backgrounder/version.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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.
|
24
|
+
FileUtils.rm_r(tmp_dir, :force => true)
|
19
25
|
end
|
20
26
|
end
|
21
27
|
end
|
File without changes
|
@@ -2,24 +2,33 @@
|
|
2
2
|
require 'spec_helper'
|
3
3
|
require 'backgrounder/workers/process_asset'
|
4
4
|
|
5
|
-
describe
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
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
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
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
|
+
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-
|
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.
|
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
|