Change remote media files to be downloaded outside of transactions (#21796)
This commit is contained in:
		| @@ -210,6 +210,8 @@ class MediaAttachment < ApplicationRecord | ||||
|  | ||||
|   default_scope { order(id: :asc) } | ||||
|  | ||||
|   attr_accessor :skip_download | ||||
|  | ||||
|   def local? | ||||
|     remote_url.blank? | ||||
|   end | ||||
|   | ||||
| @@ -45,6 +45,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService | ||||
|         create_edits! | ||||
|       end | ||||
|  | ||||
|       download_media_files! | ||||
|       queue_poll_notifications! | ||||
|  | ||||
|       next unless significant_changes? | ||||
| @@ -66,12 +67,12 @@ class ActivityPub::ProcessStatusUpdateService < BaseService | ||||
|   def update_media_attachments! | ||||
|     previous_media_attachments     = @status.media_attachments.to_a | ||||
|     previous_media_attachments_ids = @status.ordered_media_attachment_ids || previous_media_attachments.map(&:id) | ||||
|     next_media_attachments         = [] | ||||
|     @next_media_attachments        = [] | ||||
|  | ||||
|     as_array(@json['attachment']).each do |attachment| | ||||
|       media_attachment_parser = ActivityPub::Parser::MediaAttachmentParser.new(attachment) | ||||
|  | ||||
|       next if media_attachment_parser.remote_url.blank? || next_media_attachments.size > 4 | ||||
|       next if media_attachment_parser.remote_url.blank? || @next_media_attachments.size > 4 | ||||
|  | ||||
|       begin | ||||
|         media_attachment   = previous_media_attachments.find { |previous_media_attachment| previous_media_attachment.remote_url == media_attachment_parser.remote_url } | ||||
| @@ -87,34 +88,39 @@ class ActivityPub::ProcessStatusUpdateService < BaseService | ||||
|         media_attachment.focus                = media_attachment_parser.focus | ||||
|         media_attachment.thumbnail_remote_url = media_attachment_parser.thumbnail_remote_url | ||||
|         media_attachment.blurhash             = media_attachment_parser.blurhash | ||||
|         media_attachment.status_id            = @status.id | ||||
|         media_attachment.skip_download        = unsupported_media_type?(media_attachment_parser.file_content_type) || skip_download? | ||||
|         media_attachment.save! | ||||
|  | ||||
|         next_media_attachments << media_attachment | ||||
|  | ||||
|         next if unsupported_media_type?(media_attachment_parser.file_content_type) || skip_download? | ||||
|  | ||||
|         begin | ||||
|           media_attachment.download_file! if media_attachment.remote_url_previously_changed? | ||||
|           media_attachment.download_thumbnail! if media_attachment.thumbnail_remote_url_previously_changed? | ||||
|           media_attachment.save | ||||
|         rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError | ||||
|           RedownloadMediaWorker.perform_in(rand(30..600).seconds, media_attachment.id) | ||||
|         end | ||||
|         @next_media_attachments << media_attachment | ||||
|       rescue Addressable::URI::InvalidURIError => e | ||||
|         Rails.logger.debug "Invalid URL in attachment: #{e}" | ||||
|       end | ||||
|     end | ||||
|  | ||||
|     added_media_attachments = next_media_attachments - previous_media_attachments | ||||
|     added_media_attachments = @next_media_attachments - previous_media_attachments | ||||
|  | ||||
|     MediaAttachment.where(id: added_media_attachments.map(&:id)).update_all(status_id: @status.id) | ||||
|  | ||||
|     @status.ordered_media_attachment_ids = next_media_attachments.map(&:id) | ||||
|     @status.media_attachments.reload | ||||
|     @status.ordered_media_attachment_ids = @next_media_attachments.map(&:id) | ||||
|  | ||||
|     @media_attachments_changed = true if @status.ordered_media_attachment_ids != previous_media_attachments_ids | ||||
|   end | ||||
|  | ||||
|   def download_media_files! | ||||
|     @next_media_attachments.each do |media_attachment| | ||||
|       next if media_attachment.skip_download | ||||
|  | ||||
|       media_attachment.download_file! if media_attachment.remote_url_previously_changed? | ||||
|       media_attachment.download_thumbnail! if media_attachment.thumbnail_remote_url_previously_changed? | ||||
|       media_attachment.save | ||||
|     rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError | ||||
|       RedownloadMediaWorker.perform_in(rand(30..600).seconds, media_attachment.id) | ||||
|     rescue Seahorse::Client::NetworkingError => e | ||||
|       Rails.logger.warn "Error storing media attachment: #{e}" | ||||
|     end | ||||
|  | ||||
|     @status.media_attachments.reload | ||||
|   end | ||||
|  | ||||
|   def update_poll!(allow_significant_changes: true) | ||||
|     previous_poll        = @status.preloadable_poll | ||||
|     @previous_expires_at = previous_poll&.expires_at | ||||
|   | ||||
		Reference in New Issue
	
	Block a user