mirror of https://github.com/mastodon/mastodon
				
				
				
			Change local media attachments to perform heavy processing asynchronously (#13210)
Fix #9106pull/13220/head
							parent
							
								
									764b89939f
								
							
						
					
					
						commit
						9660aa4543
					
				@ -0,0 +1,12 @@
 | 
			
		||||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
class Api::V2::MediaController < Api::V1::MediaController
 | 
			
		||||
  def create
 | 
			
		||||
    @media_attachment = current_account.media_attachments.create!({ delay_processing: true }.merge(media_attachment_params))
 | 
			
		||||
    render json: @media_attachment, serializer: REST::MediaAttachmentSerializer, status: 202
 | 
			
		||||
  rescue Paperclip::Errors::NotIdentifiedByImageMagickError
 | 
			
		||||
    render json: file_type_error, status: 422
 | 
			
		||||
  rescue Paperclip::Error
 | 
			
		||||
    render json: processing_error, status: 500
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
@ -0,0 +1,34 @@
 | 
			
		||||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
class PostProcessMediaWorker
 | 
			
		||||
  include Sidekiq::Worker
 | 
			
		||||
 | 
			
		||||
  sidekiq_options retry: 1, dead: false
 | 
			
		||||
 | 
			
		||||
  sidekiq_retries_exhausted do |msg|
 | 
			
		||||
    media_attachment_id = msg['args'].first
 | 
			
		||||
 | 
			
		||||
    ActiveRecord::Base.connection_pool.with_connection do
 | 
			
		||||
      begin
 | 
			
		||||
        media_attachment = MediaAttachment.find(media_attachment_id)
 | 
			
		||||
        media_attachment.processing = :failed
 | 
			
		||||
        media_attachment.save
 | 
			
		||||
      rescue ActiveRecord::RecordNotFound
 | 
			
		||||
        true
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    Sidekiq.logger.error("Processing media attachment #{media_attachment_id} failed with #{msg['error_message']}")
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def perform(media_attachment_id)
 | 
			
		||||
    media_attachment = MediaAttachment.find(media_attachment_id)
 | 
			
		||||
    media_attachment.processing = :in_progress
 | 
			
		||||
    media_attachment.save
 | 
			
		||||
    media_attachment.file.reprocess_original!
 | 
			
		||||
    media_attachment.processing = :complete
 | 
			
		||||
    media_attachment.save
 | 
			
		||||
  rescue ActiveRecord::RecordNotFound
 | 
			
		||||
    true
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
@ -0,0 +1,5 @@
 | 
			
		||||
class AddProcessingToMediaAttachments < ActiveRecord::Migration[5.2]
 | 
			
		||||
  def change
 | 
			
		||||
    add_column :media_attachments, :processing, :integer
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
@ -0,0 +1,30 @@
 | 
			
		||||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
module Paperclip
 | 
			
		||||
  module AttachmentExtensions
 | 
			
		||||
    # We overwrite this method to support delayed processing in
 | 
			
		||||
    # Sidekiq. Since we process the original file to reduce disk
 | 
			
		||||
    # usage, and we still want to generate thumbnails straight
 | 
			
		||||
    # away, it's the only style we need to exclude
 | 
			
		||||
    def process_style?(style_name, style_args)
 | 
			
		||||
      if style_name == :original && instance.respond_to?(:delay_processing?) && instance.delay_processing?
 | 
			
		||||
        false
 | 
			
		||||
      else
 | 
			
		||||
        style_args.empty? || style_args.include?(style_name)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def reprocess_original!
 | 
			
		||||
      old_original_path = path(:original)
 | 
			
		||||
      reprocess!(:original)
 | 
			
		||||
      new_original_path = path(:original)
 | 
			
		||||
 | 
			
		||||
      if new_original_path != old_original_path
 | 
			
		||||
        @queued_for_delete << old_original_path
 | 
			
		||||
        flush_deletes
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
Paperclip::Attachment.prepend(Paperclip::AttachmentExtensions)
 | 
			
		||||
					Loading…
					
					
				
		Reference in New Issue