about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFire Demon <firedemon@creature.cafe>2020-07-20 14:42:48 -0500
committerFire Demon <firedemon@creature.cafe>2020-08-30 05:44:01 -0500
commit2c0a92bc3f85f8668fff66fcf942a1878363426d (patch)
tree9c0e24f5f954c12f2ee04c29090f30d7739e8d97
parent3366a957219b15f5ab6f6eabbf5466e1e12082de (diff)
[Bug] Purge cached status when processing command tags and edits
-rw-r--r--app/lib/command_tag/processor.rb15
-rw-r--r--app/services/publish_status_service.rb40
2 files changed, 46 insertions, 9 deletions
diff --git a/app/lib/command_tag/processor.rb b/app/lib/command_tag/processor.rb
index b122b9e8d..74dcb047d 100644
--- a/app/lib/command_tag/processor.rb
+++ b/app/lib/command_tag/processor.rb
@@ -1,6 +1,7 @@
 # frozen_string_literal: true
 
 class CommandTag::Processor
+  include Redisable
   include CommandTag::Commands
 
   STATEMENT_RE = /^\s*#!\s*([^\n]+ (?:start|begin|do)$.*)\n\s*#!\s*(?:end|stop|done)\s*$|^\s*#!\s*(.*?)\s*$/im.freeze
@@ -18,6 +19,8 @@ class CommandTag::Processor
   end
 
   def process!
+    reset_status_caches
+
     @statements = parse_statements
     @text = @text.gsub(STATEMENT_STRIP_RE, '').split("\n")
 
@@ -42,6 +45,7 @@ class CommandTag::Processor
     end
 
     %w(at_end once_at_end).each { |suffix| execute_statements(suffix) }
+    reset_status_caches
   end
 
   private
@@ -65,6 +69,17 @@ class CommandTag::Processor
     end
   end
 
+  def reset_status_caches
+    [@status, @parent].each do |status|
+      next unless @account.id == status&.account_id
+
+      Rails.cache.delete_matched("statuses/#{status.id}-*")
+      Rails.cache.delete("statuses/#{status.id}")
+      Rails.cache.delete(status)
+      redis.zremrangebyscore("spam_check:#{status.account.id}", status.id, status.id)
+    end
+  end
+
   def author_of_status?
     @account.id == @status.account_id
   end
diff --git a/app/services/publish_status_service.rb b/app/services/publish_status_service.rb
index 737186a17..f81b43a97 100644
--- a/app/services/publish_status_service.rb
+++ b/app/services/publish_status_service.rb
@@ -1,22 +1,44 @@
 # frozen_string_literal: true
 class PublishStatusService < BaseService
+  include Redisable
+
   def call(status)
     return if status.published?
 
-    status.update!(published: true)
+    @status = status
 
-    ProcessMentionsService.new.call(status)
+    update_status!
+    reset_status_caches
+    distribute
+    bump_potential_friendship!
+  end
 
-    LinkCrawlWorker.perform_in(rand(1..30).seconds, status.id) unless status.spoiler_text?
-    DistributionWorker.perform_async(status.id)
-    ActivityPub::DistributionWorker.perform_async(status.id) if status.local? && !status.local_only?
+  private
 
-    return if !status.reply? || status.account.id == status.in_reply_to_account_id
+  def update_status!
+    @status.update!(published: true)
+    ProcessMentionsService.new.call(@status)
+  end
 
-    ActivityTracker.increment('activity:interactions')
+  def reset_status_caches
+    Rails.cache.delete_matched("statuses/#{@status.id}-*")
+    Rails.cache.delete("statuses/#{@status.id}")
+    Rails.cache.delete(@status)
+    redis.zremrangebyscore("spam_check:#{@status.account.id}", @status.id, @status.id)
+  end
 
-    return if status.account.following?(status.in_reply_to_account_id)
+  def distribute
+    LinkCrawlWorker.perform_in(rand(1..30).seconds, @status.id) unless @status.spoiler_text?
+    DistributionWorker.perform_async(@status.id)
+    ActivityPub::DistributionWorker.perform_async(@status.id) if @status.local? && !@status.local_only?
+  end
+
+  def bump_potential_friendship!
+    return if !@status.reply? || @status.account.id == @status.in_reply_to_account_id
+
+    ActivityTracker.increment('activity:interactions')
+    return if @status.account.following?(@status.in_reply_to_account_id)
 
-    PotentialFriendshipTracker.record(status.account.id, status.in_reply_to_account_id, :reply)
+    PotentialFriendshipTracker.record(@status.account.id, @status.in_reply_to_account_id, :reply)
   end
 end