carrierwave_backgrounder_revived 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.rspec +2 -0
- data/.travis.yml +15 -0
- data/CHANGELOG.md +99 -0
- data/Gemfile +4 -0
- data/README.md +229 -0
- data/Rakefile +12 -0
- data/carrierwave_backgrounder.gemspec +25 -0
- data/lib/backgrounder/delay.rb +26 -0
- data/lib/backgrounder/orm/activemodel.rb +36 -0
- data/lib/backgrounder/orm/base.rb +120 -0
- data/lib/backgrounder/orm/data_mapper.rb +63 -0
- data/lib/backgrounder/railtie.rb +25 -0
- data/lib/backgrounder/support/backends.rb +94 -0
- data/lib/backgrounder/version.rb +5 -0
- data/lib/backgrounder/workers.rb +6 -0
- data/lib/backgrounder/workers/base.rb +42 -0
- data/lib/backgrounder/workers/class_methods.rb +14 -0
- data/lib/backgrounder/workers/process_asset.rb +10 -0
- data/lib/backgrounder/workers/process_asset_mixin.rb +28 -0
- data/lib/backgrounder/workers/store_asset.rb +10 -0
- data/lib/backgrounder/workers/store_asset_mixin.rb +43 -0
- data/lib/carrierwave_backgrounder.rb +35 -0
- data/lib/generators/carrierwave_backgrounder/USAGE +8 -0
- data/lib/generators/carrierwave_backgrounder/install_generator.rb +20 -0
- data/lib/generators/carrierwave_backgrounder/templates/config/initializers/carrierwave_backgrounder.rb +10 -0
- data/spec/backgrounder/orm/activemodel_spec.rb +97 -0
- data/spec/backgrounder/orm/base_spec.rb +74 -0
- data/spec/backgrounder/support/backends_spec.rb +234 -0
- data/spec/backgrounder/workers/fixtures/images/test.jpg +0 -0
- data/spec/backgrounder/workers/process_asset_spec.rb +70 -0
- data/spec/backgrounder/workers/store_asset_spec.rb +137 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/support/backend_constants.rb +58 -0
- data/spec/support/mock_worker.rb +22 -0
- metadata +151 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ccace65db06c5331ce7b76332f8089fa38ee077b
|
4
|
+
data.tar.gz: 2fd227027c62fa5edda188835ef027bfbfce1621
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2b563d3c48e2361ab57003ec3d036e1b0c990ad19ab2ff14c41bbffce2e06935395f547d4d81d58b76e93ea75435d107145ff16abd00d822a6a4b2a96fbc3a0d
|
7
|
+
data.tar.gz: 0e74a658376645778a376bdb542a37d87e5eddf3dd3af1ee22af506160185af47b65c1abb6a9c2719b02337c2b52b153f96817d7c6d3bc983d28e59c1f0cc7d9
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
|
2
|
+
## 0.4.2
|
3
|
+
|
4
|
+
### enhancements
|
5
|
+
* Allow overridden worker to set a queue name
|
6
|
+
* [#190] Respect Carrierwave's enable_processing flag if set to false [jherdman]
|
7
|
+
|
8
|
+
### bug fixes
|
9
|
+
* [#216] Fix for NoMethodError: undefined method `read' for nil:NilClass [kntmrkm]
|
10
|
+
|
11
|
+
## 0.4.1
|
12
|
+
|
13
|
+
### enhancements
|
14
|
+
* [#179] Set column_processing to false instead of nil [mockdeep]
|
15
|
+
|
16
|
+
## 0.4.0
|
17
|
+
|
18
|
+
### enhancements
|
19
|
+
* [#175] SuckerPunch v1.0 support (no longer support < 1.0). [janko-m]
|
20
|
+
|
21
|
+
### bug fixes
|
22
|
+
* [#176] Check if record exists before running backgrounder [gdott9]
|
23
|
+
* [#169] Correctly remove files on update if marked for deletion [sunny]
|
24
|
+
|
25
|
+
## 0.3.0
|
26
|
+
|
27
|
+
### enhancements
|
28
|
+
* [#123] Fail silently when record not found in worker. [DouweM]
|
29
|
+
|
30
|
+
## 0.2.2
|
31
|
+
|
32
|
+
### bug fixes
|
33
|
+
* [#141] Fix naming collisions of support module by namespacing.
|
34
|
+
|
35
|
+
## 0.2.1
|
36
|
+
|
37
|
+
### enhancements
|
38
|
+
* [#119] Add support for SuckerPunch [rewritten].
|
39
|
+
|
40
|
+
### bug fixes
|
41
|
+
* [#115] column_remove! should not trigger a background job
|
42
|
+
* [#112] Raise a NoMethodError when using backend= instead of silent failure.
|
43
|
+
|
44
|
+
## 0.2.0
|
45
|
+
|
46
|
+
### enhancements
|
47
|
+
* [Breaking Change] Require configure block to be set in an initializer removing autodetect backend.
|
48
|
+
|
49
|
+
### bug fixes
|
50
|
+
* [#108] Remove the need to set an order in the Gemfile when using sidekiq [matthewsmart].
|
51
|
+
|
52
|
+
## 0.1.5
|
53
|
+
|
54
|
+
### bug fixes
|
55
|
+
* [Revert #108] This is a breaking change and will be released in 0.2.0.
|
56
|
+
|
57
|
+
## 0.1.4
|
58
|
+
|
59
|
+
### bug fixes
|
60
|
+
* [#109] Fix issue where setting Carrierwave.cache_dir to a full path would raise an exception [Sastopher].
|
61
|
+
|
62
|
+
## 0.1.3
|
63
|
+
|
64
|
+
### enhancements
|
65
|
+
* CarrierWave::Workers::ProcessAsset now uses #update_attribute when setting [column]_processing.
|
66
|
+
* [#104] Change the Sidekiq integration to use client_push [petergoldstein]
|
67
|
+
|
68
|
+
### bug fixes
|
69
|
+
* [#103] Fix determine_backend behavior so that it doesn't throw an exception [petergoldstein].
|
70
|
+
|
71
|
+
## 0.1.2
|
72
|
+
|
73
|
+
### enhancements
|
74
|
+
* Add a rails generator to generate the config file.
|
75
|
+
```bash
|
76
|
+
rails g carrierwave_backgrounder:install
|
77
|
+
```
|
78
|
+
|
79
|
+
### bug fixes
|
80
|
+
* Check [column]_cache to make sure we are processing when a form fails and [column]_cache is used.
|
81
|
+
|
82
|
+
## 0.1.1
|
83
|
+
|
84
|
+
### enhancements
|
85
|
+
* Allow passing of all options to sidekiq in config file.
|
86
|
+
|
87
|
+
### bug fixes
|
88
|
+
* Revert where sidekiq was broken due to Sidekiq::Worker not properly being included.
|
89
|
+
|
90
|
+
## 0.1.0
|
91
|
+
|
92
|
+
### enhancements
|
93
|
+
* Add support to pass options to backends allowing queue names to be set in the initializer.
|
94
|
+
* Make threadsafe. [gitt]
|
95
|
+
* Add support to immediately process jobs if :immediate is set in config backend. [Antiarchitect]
|
96
|
+
|
97
|
+
### bug fixes
|
98
|
+
* Girl Friday incorrectly referenses class #92
|
99
|
+
* Add documentation for testing with rspec #84.
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,229 @@
|
|
1
|
+
# CarrierWave Backgrounder Revived
|
2
|
+
|
3
|
+
[![Build Status](https://secure.travis-ci.org/lardawge/carrierwave_backgrounder.png)](http://travis-ci.org/lardawge/carrierwave_backgrounder)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/lardawge/carrierwave_backgrounder.png)](https://codeclimate.com/github/lardawge/carrierwave_backgrounder)
|
5
|
+
|
6
|
+
Decided to revive this project. Currently changes are;
|
7
|
+
* ActiveJob no longer errors out but is basically working as InlineJob
|
8
|
+
* Released v1.0.0 to prevent having to point to master
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'carrierwave_backgrounder_revived'
|
12
|
+
```
|
13
|
+
|
14
|
+
---
|
15
|
+
|
16
|
+
I like CarrierWave. That being said, I don't like tying up app instances waiting for images to process.
|
17
|
+
|
18
|
+
This gem addresses that by offloading processing or storage/processing to a background task.
|
19
|
+
We currently support Delayed Job, Resque, Sidekiq, SuckerPunch, Girl Friday, Qu, and Queue Classic.
|
20
|
+
|
21
|
+
## Background options
|
22
|
+
|
23
|
+
There are currently two offerings for backgrounding upload tasks which are as follows;
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
# This stores the original file with no processing/versioning.
|
27
|
+
# It will upload the original file to s3.
|
28
|
+
# This was developed to use where you do not have control over the cache location such as Heroku.
|
29
|
+
|
30
|
+
Backgrounder::ORM::Base::process_in_background
|
31
|
+
```
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
# This does nothing to the file after it is cached which makes it super fast.
|
35
|
+
# It requires a column in the database which stores the cache location set by carrierwave so the background job can access it.
|
36
|
+
# The drawback to using this method is the need for a central location to store the cached files.
|
37
|
+
# Heroku may deploy workers on separate servers from where your dyno cached the files.
|
38
|
+
#
|
39
|
+
# IMPORTANT: Only use this method if you have full control over your tmp storage directory.
|
40
|
+
|
41
|
+
Backgrounder::ORM::Base::store_in_background
|
42
|
+
```
|
43
|
+
|
44
|
+
## Installation and Usage
|
45
|
+
|
46
|
+
These instructions assume you have previously set up [CarrierWave](https://github.com/jnicklas/carrierwave) and your queuing lib of choice.
|
47
|
+
|
48
|
+
In Rails, add the following your Gemfile:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
gem 'carrierwave_backgrounder'
|
52
|
+
```
|
53
|
+
|
54
|
+
Run the generator which will create an initializer in config/initializers.
|
55
|
+
```bash
|
56
|
+
rails g carrierwave_backgrounder:install
|
57
|
+
```
|
58
|
+
|
59
|
+
You can pass additional configuration options to Girl Friday and Sidekiq:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
CarrierWave::Backgrounder.configure do |c|
|
63
|
+
c.backend :girl_friday, queue: :awesome_queue, size: 3, store: GirlFriday::Store::Redis
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
In your CarrierWave uploader file:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
class AvatarUploader < CarrierWave::Uploader::Base
|
71
|
+
include ::CarrierWave::Backgrounder::Delay
|
72
|
+
|
73
|
+
#etc...
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
### To use process_in_background
|
78
|
+
|
79
|
+
In your model:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
mount_uploader :avatar, AvatarUploader
|
83
|
+
process_in_background :avatar
|
84
|
+
```
|
85
|
+
|
86
|
+
Optionally you can add a column to the database which will be set to `true` when
|
87
|
+
the background processing is started and to `false` when the background processing is complete.
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
add_column :users, :avatar_processing, :boolean, null: false, default: false
|
91
|
+
```
|
92
|
+
|
93
|
+
### To use store_in_background
|
94
|
+
|
95
|
+
In your model:
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
mount_uploader :avatar, AvatarUploader
|
99
|
+
store_in_background :avatar
|
100
|
+
```
|
101
|
+
|
102
|
+
Add a column to the model you want to background which will store the temp file location:
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
add_column :users, :avatar_tmp, :string
|
106
|
+
```
|
107
|
+
|
108
|
+
## Usage Tips
|
109
|
+
|
110
|
+
### Bypass backgrounding
|
111
|
+
If you need to process/store the upload immediately:
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
@user.process_<column>_upload = true
|
115
|
+
```
|
116
|
+
|
117
|
+
This must be set before you assign an upload:
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
# In a controller
|
121
|
+
@user = User.new
|
122
|
+
@user.process_avatar_upload = true
|
123
|
+
@user.attributes = params[:user]
|
124
|
+
```
|
125
|
+
|
126
|
+
### Override worker
|
127
|
+
To override the worker in cases where additional methods need to be called or you have app specific requirements, pass the worker class as the
|
128
|
+
second argument:
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
process_in_background :avatar, MyParanoidWorker
|
132
|
+
```
|
133
|
+
|
134
|
+
Then create a worker that subclasses carrierwave_backgrounder's worker:
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
class MyParanoidWorker < ::CarrierWave::Workers::ProcessAsset
|
138
|
+
# ...or subclass CarrierWave::Workers::StoreAsset if you're using store_in_background
|
139
|
+
|
140
|
+
def error(job, exception)
|
141
|
+
report_job_failure # or whatever
|
142
|
+
end
|
143
|
+
|
144
|
+
# other hooks you might care about
|
145
|
+
end
|
146
|
+
```
|
147
|
+
|
148
|
+
### ActiveJob
|
149
|
+
Use overriden worker that inherits from ActiveJob::Base and includes relevant worker mixin:
|
150
|
+
```ruby
|
151
|
+
class MyActiveJobWorker < ActiveJob::Base
|
152
|
+
include ::CarrierWave::Workers::ProcessAssetMixin
|
153
|
+
# ... or include ::CarrierWave::Workers::StoreAssetMixin
|
154
|
+
|
155
|
+
after_perform do
|
156
|
+
# your code here
|
157
|
+
end
|
158
|
+
|
159
|
+
# Sometimes job gets performed before the file is uploaded and ready.
|
160
|
+
# You can define how to handle that case by overriding `when_not_ready` method
|
161
|
+
# (by default it does nothing)
|
162
|
+
def when_not_ready
|
163
|
+
retry_job
|
164
|
+
end
|
165
|
+
end
|
166
|
+
```
|
167
|
+
Don't forget to set `active_job` as a backend in the config:
|
168
|
+
```ruby
|
169
|
+
CarrierWave::Backgrounder.configure do |c|
|
170
|
+
c.backend :active_job, queue: :carrierwave
|
171
|
+
end
|
172
|
+
```
|
173
|
+
|
174
|
+
### Testing with Rspec
|
175
|
+
We use the after_commit hook when using active_record. This creates a problem when testing with Rspec because after_commit never gets fired
|
176
|
+
if you're using trasactional fixtures. One solution to the problem is to use the [TestAfterCommit gem](https://github.com/grosser/test_after_commit).
|
177
|
+
There are various other solutions in which case google is your friend.
|
178
|
+
|
179
|
+
### Uploaders mounted on mongoid embedded documents
|
180
|
+
The workers fetch the document with the mounted uploader using the model class name and id. Uploads on embedded documents
|
181
|
+
cannot be obtained this way. If the position of the document in the root document structure is known, a workaround is to override the embedded models
|
182
|
+
find method like this:
|
183
|
+
|
184
|
+
```ruby
|
185
|
+
class SomeRootDocument
|
186
|
+
include Mongoid::Document
|
187
|
+
|
188
|
+
embeds_many :embedded_documents
|
189
|
+
end
|
190
|
+
|
191
|
+
class EmbeddedDocument
|
192
|
+
include Mongoid::Document
|
193
|
+
|
194
|
+
embedded_in :some_root_document
|
195
|
+
|
196
|
+
mount_uploader :image, ImageUploader
|
197
|
+
process_in_background :image
|
198
|
+
|
199
|
+
def self.find(id)
|
200
|
+
bson_id = Moped::BSON::ObjectId.from_string(id) # needed for Mongoid 3
|
201
|
+
|
202
|
+
root = SomeRootDocument.where('embedded_documents._id' => bson_id).first
|
203
|
+
root.embedded_documents.find(id)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
```
|
207
|
+
|
208
|
+
## License
|
209
|
+
|
210
|
+
Copyright (c) 2011 Larry Sprock
|
211
|
+
|
212
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
213
|
+
a copy of this software and associated documentation files (the
|
214
|
+
"Software"), to deal in the Software without restriction, including
|
215
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
216
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
217
|
+
permit persons to whom the Software is furnished to do so, subject to
|
218
|
+
the following conditions:
|
219
|
+
|
220
|
+
The above copyright notice and this permission notice shall be
|
221
|
+
included in all copies or substantial portions of the Software.
|
222
|
+
|
223
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
224
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
225
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
226
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
227
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
228
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
229
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'bundler'
|
3
|
+
Bundler::GemHelper.install_tasks
|
4
|
+
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
desc "Run all examples"
|
7
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
8
|
+
t.rspec_opts = ["-c", "-f progress", "-r ./spec/spec_helper.rb"]
|
9
|
+
t.pattern = 'spec/**/*_spec.rb'
|
10
|
+
end
|
11
|
+
|
12
|
+
task :default => :spec
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "backgrounder/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "carrierwave_backgrounder_revived"
|
7
|
+
s.version = CarrierWave::Backgrounder::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Larry Sprock"]
|
10
|
+
s.email = ["larry@lucidbleu.com"]
|
11
|
+
s.homepage = "https://github.com/lardawge/carrierwave_backgrounder"
|
12
|
+
s.licenses = ["MIT"]
|
13
|
+
s.summary = %q{Offload CarrierWave's image processing and storage to a background process using Delayed Job, Resque, Sidekiq, Qu, Queue Classic or Girl Friday}
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_dependency "carrierwave", [">= 0.5", "< 2.0"]
|
21
|
+
s.add_dependency "mime-types", ["~> 2.99"]
|
22
|
+
|
23
|
+
s.add_development_dependency "rspec", ["~> 3.5.0"]
|
24
|
+
s.add_development_dependency "rake"
|
25
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module CarrierWave
|
2
|
+
module Backgrounder
|
3
|
+
|
4
|
+
module Delay
|
5
|
+
def cache_versions!(new_file)
|
6
|
+
super if proceed_with_versioning?
|
7
|
+
end
|
8
|
+
|
9
|
+
def store_versions!(*args)
|
10
|
+
super if proceed_with_versioning?
|
11
|
+
end
|
12
|
+
|
13
|
+
def process!(new_file=nil)
|
14
|
+
super if proceed_with_versioning?
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def proceed_with_versioning?
|
20
|
+
!model.respond_to?(:"process_#{mounted_as}_upload") && enable_processing ||
|
21
|
+
!!(model.send(:"process_#{mounted_as}_upload") && enable_processing)
|
22
|
+
end
|
23
|
+
end # Delay
|
24
|
+
|
25
|
+
end # Backgrounder
|
26
|
+
end # CarrierWave
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module CarrierWave
|
4
|
+
module Backgrounder
|
5
|
+
module ORM
|
6
|
+
|
7
|
+
module ActiveModel
|
8
|
+
include CarrierWave::Backgrounder::ORM::Base
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def _define_shared_backgrounder_methods(mod, column, worker)
|
13
|
+
before_save :"set_#{column}_processing", :if => :"enqueue_#{column}_background_job?"
|
14
|
+
send _supported_callback, :"enqueue_#{column}_background_job", :if => :"enqueue_#{column}_background_job?"
|
15
|
+
|
16
|
+
super
|
17
|
+
|
18
|
+
define_method :"#{column}_updated?" do
|
19
|
+
options = self.class.uploader_options[column] || {}
|
20
|
+
serialization_column = options[:mount_on] || column
|
21
|
+
|
22
|
+
send(:"#{serialization_column}_changed?") || # after_save support
|
23
|
+
previous_changes.has_key?(:"#{serialization_column}") || # after_commit support
|
24
|
+
send(:"remote_#{column}_url").present? || # Remote upload support
|
25
|
+
send(:"#{column}_cache").present? # Form failure support
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def _supported_callback
|
30
|
+
respond_to?(:after_commit) ? :after_commit : :after_save
|
31
|
+
end
|
32
|
+
end # ActiveModel
|
33
|
+
|
34
|
+
end # ORM
|
35
|
+
end # Backgrounder
|
36
|
+
end # CarrierWave
|