carrierwave_backgrounder_revived 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +15 -0
  5. data/CHANGELOG.md +99 -0
  6. data/Gemfile +4 -0
  7. data/README.md +229 -0
  8. data/Rakefile +12 -0
  9. data/carrierwave_backgrounder.gemspec +25 -0
  10. data/lib/backgrounder/delay.rb +26 -0
  11. data/lib/backgrounder/orm/activemodel.rb +36 -0
  12. data/lib/backgrounder/orm/base.rb +120 -0
  13. data/lib/backgrounder/orm/data_mapper.rb +63 -0
  14. data/lib/backgrounder/railtie.rb +25 -0
  15. data/lib/backgrounder/support/backends.rb +94 -0
  16. data/lib/backgrounder/version.rb +5 -0
  17. data/lib/backgrounder/workers.rb +6 -0
  18. data/lib/backgrounder/workers/base.rb +42 -0
  19. data/lib/backgrounder/workers/class_methods.rb +14 -0
  20. data/lib/backgrounder/workers/process_asset.rb +10 -0
  21. data/lib/backgrounder/workers/process_asset_mixin.rb +28 -0
  22. data/lib/backgrounder/workers/store_asset.rb +10 -0
  23. data/lib/backgrounder/workers/store_asset_mixin.rb +43 -0
  24. data/lib/carrierwave_backgrounder.rb +35 -0
  25. data/lib/generators/carrierwave_backgrounder/USAGE +8 -0
  26. data/lib/generators/carrierwave_backgrounder/install_generator.rb +20 -0
  27. data/lib/generators/carrierwave_backgrounder/templates/config/initializers/carrierwave_backgrounder.rb +10 -0
  28. data/spec/backgrounder/orm/activemodel_spec.rb +97 -0
  29. data/spec/backgrounder/orm/base_spec.rb +74 -0
  30. data/spec/backgrounder/support/backends_spec.rb +234 -0
  31. data/spec/backgrounder/workers/fixtures/images/test.jpg +0 -0
  32. data/spec/backgrounder/workers/process_asset_spec.rb +70 -0
  33. data/spec/backgrounder/workers/store_asset_spec.rb +137 -0
  34. data/spec/spec_helper.rb +20 -0
  35. data/spec/support/backend_constants.rb +58 -0
  36. data/spec/support/mock_worker.rb +22 -0
  37. metadata +151 -0
@@ -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
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ vendor/*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format progress
2
+ --colour
@@ -0,0 +1,15 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - 2.1
7
+ - 2.2
8
+ - ruby-head
9
+
10
+ before_install:
11
+ - gem install bundler
12
+
13
+ matrix:
14
+ allow_failures:
15
+ - rvm: ruby-head
@@ -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
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in carrierwave_backgrounder.gemspec
4
+ gemspec
@@ -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.
@@ -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