Skip to content

Commit fbb230e

Browse files
authored
Merge pull request rails#51030 from searls/queue-approach-to-preview-image-race-condition
Fixes race condition for multiple preprocessed video variants
2 parents 6929568 + 0f9638e commit fbb230e

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# frozen_string_literal: true
2+
3+
class ActiveStorage::PreviewImageJob < ActiveStorage::BaseJob
4+
queue_as { ActiveStorage.queues[:preview_image] }
5+
6+
discard_on ActiveRecord::RecordNotFound, ActiveStorage::UnrepresentableError
7+
retry_on ActiveStorage::IntegrityError, attempts: 10, wait: :polynomially_longer
8+
9+
def perform(blob, variations)
10+
blob.preview({}).processed
11+
12+
variations.each do |transformations|
13+
blob.preprocessed(transformations)
14+
end
15+
end
16+
end

activestorage/app/models/active_storage/attachment.rb

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,18 @@ def mirror_blob_later
132132
end
133133

134134
def transform_variants_later
135-
named_variants.each do |_name, named_variant|
136-
blob.preprocessed(named_variant.transformations) if named_variant.preprocessed?(record)
135+
preprocessed_variations = named_variants.filter_map { |_name, named_variant|
136+
if named_variant.preprocessed?(record)
137+
named_variant.transformations
138+
end
139+
}
140+
141+
if blob.preview_image_needed_before_processing_variants?
142+
blob.create_preview_image_later(preprocessed_variations)
143+
else
144+
preprocessed_variations.each do |transformations|
145+
blob.preprocessed(transformations)
146+
end
137147
end
138148
end
139149

activestorage/app/models/active_storage/blob/representable.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,14 @@ def representable?
9898
variable? || previewable?
9999
end
100100

101+
def preview_image_needed_before_processing_variants?
102+
previewable? && !preview_image.attached?
103+
end
104+
105+
def create_preview_image_later(variations) # :nodoc:
106+
ActiveStorage::PreviewImageJob.perform_later(self, variations) if representable?
107+
end
108+
101109
def preprocessed(transformations) # :nodoc:
102110
ActiveStorage::TransformJob.perform_later(self, transformations) if representable?
103111
end

0 commit comments

Comments
 (0)