]> cat aescling's git repositories - mastodon.git/commitdiff
After blocking domain with reject_media, invalidate cache (#6679)
authorEugen Rochko <eugen@zeonfederated.com>
Thu, 8 Mar 2018 05:59:42 +0000 (06:59 +0100)
committerGitHub <noreply@github.com>
Thu, 8 Mar 2018 05:59:42 +0000 (06:59 +0100)
Media attachments are part of the association cache of statuses,
since they are presumed to be immutable. Unless this cache is
cleared manually, the statuses will continue to look like they
have media embedded.

app/services/block_domain_service.rb
lib/tasks/mastodon.rake

index eefdc0dbf9a136af6cf63b2bf3426e95150faf7a..d082de40b9b45057b5ae7e416c6d0b078e5f2a20 100644 (file)
@@ -5,13 +5,14 @@ class BlockDomainService < BaseService
 
   def call(domain_block)
     @domain_block = domain_block
-    process_domain_block
+    process_domain_block!
   end
 
   private
 
-  def process_domain_block
+  def process_domain_block!
     clear_media! if domain_block.reject_media?
+
     if domain_block.silence?
       silence_accounts!
     elsif domain_block.suspend?
@@ -19,14 +20,26 @@ class BlockDomainService < BaseService
     end
   end
 
+  def invalidate_association_caches!
+    # Normally, associated models of a status are immutable (except for accounts)
+    # so they are aggressively cached. After updating the media attachments to no
+    # longer point to a local file, we need to clear the cache to make those
+    # changes appear in the API and UI
+    @affected_status_ids.each { |id| Rails.cache.delete_matched("statuses/#{id}-*") }
+  end
+
   def silence_accounts!
     blocked_domain_accounts.in_batches.update_all(silenced: true)
   end
 
   def clear_media!
-    clear_account_images
-    clear_account_attachments
-    clear_emojos
+    @affected_status_ids = []
+
+    clear_account_images!
+    clear_account_attachments!
+    clear_emojos!
+
+    invalidate_association_caches!
   end
 
   def suspend_accounts!
@@ -36,23 +49,25 @@ class BlockDomainService < BaseService
     end
   end
 
-  def clear_account_images
+  def clear_account_images!
     blocked_domain_accounts.find_each do |account|
-      account.avatar.destroy
-      account.header.destroy
+      account.avatar.destroy if account.avatar.exists?
+      account.header.destroy if account.header.exists?
       account.save
     end
   end
 
-  def clear_account_attachments
+  def clear_account_attachments!
     media_from_blocked_domain.find_each do |attachment|
-      attachment.file.destroy
+      @affected_status_ids << attachment.status_id if attachment.status_id.present?
+
+      attachment.file.destroy if attachment.file.exists?
       attachment.type = :unknown
       attachment.save
     end
   end
 
-  def clear_emojos
+  def clear_emojos!
     emojis_from_blocked_domains.destroy_all
   end
 
index 9202b4839cee233a89fdb83e07bc9d16b96297b6..0b011bf57fd6ae55d8413e8afa5d481a51c62b3d 100644 (file)
@@ -476,10 +476,10 @@ namespace :mastodon do
       time_ago = ENV.fetch('NUM_DAYS') { 7 }.to_i.days.ago
 
       MediaAttachment.where.not(remote_url: '').where.not(file_file_name: nil).where('created_at < ?', time_ago).find_each do |media|
-        if media.file.exists?
-          media.file.destroy
-          media.save
-        end
+        next unless media.file.exists?
+
+        media.file.destroy
+        media.save
       end
     end