]> cat aescling's git repositories - mastodon.git/commitdiff
Fix some RedisLocks auto-releasing too fast (#16276)
authorClaire <claire.github-309c@sitedethib.com>
Wed, 19 May 2021 21:52:08 +0000 (23:52 +0200)
committerGitHub <noreply@github.com>
Wed, 19 May 2021 21:52:08 +0000 (23:52 +0200)
* Fix Delete and Create-related locks expiring too fast

Fixes #16238

By default, RedisLock expires after 10 seconds, which may not be enough to
process statuses, especially when those have attached media files.

This commit extends those 10 seconds to 15 minutes, which should be plenty
enough to handle any status, while being short enough to not waste many
sidekiq job retries in the exceedingly rare case in which a sidekiq process
would crash when processing a `Create` or `Delete`.

* Fix other RedisLock autorelease durations

Fixes #15645

- things that only perform a few simple database queries (e.g. finding and
  saving a record) have been left unchanged, so they'll still use the default
  10s duration
- things that perform significantly more complex database queries have been
  changed to a 5 minutes timeout
- things that perform multiple HTTP queries have been changed to a 15 minutes
  timeout

app/lib/activitypub/activity.rb
app/services/activitypub/process_account_service.rb
app/services/fetch_link_card_service.rb
app/services/remove_status_service.rb
app/services/resolve_account_service.rb
app/workers/distribution_worker.rb

index 3baee4ca4653452ae66a3ad002bbe9ca63b5d60c..d2ec122a4daea936364e254d42acbfd16e9265ea 100644 (file)
@@ -216,8 +216,8 @@ class ActivityPub::Activity
     redis.del(key)
   end
 
-  def lock_or_fail(key)
-    RedisLock.acquire({ redis: Redis.current, key: key }) do |lock|
+  def lock_or_fail(key, expire_after = 15.minutes.seconds)
+    RedisLock.acquire({ redis: Redis.current, key: key, autorelease: expire_after }) do |lock|
       if lock.acquired?
         yield
       else
index 7e268f4d49d5d020f538beb2e5c8fb8a2f45fafa..4ab6912e5d409f7a77cc8065eb0493c470abfc5e 100644 (file)
@@ -290,7 +290,7 @@ class ActivityPub::ProcessAccountService < BaseService
   end
 
   def lock_options
-    { redis: Redis.current, key: "process_account:#{@uri}" }
+    { redis: Redis.current, key: "process_account:#{@uri}", autorelease: 15.minutes.seconds }
   end
 
   def process_tags
index fa1636e41116582c92a199eb82b99e2b744bebd2..5732ce8ace49af70f7baccf173615b2ee4db7b15 100644 (file)
@@ -175,6 +175,6 @@ class FetchLinkCardService < BaseService
   end
 
   def lock_options
-    { redis: Redis.current, key: "fetch:#{@url}" }
+    { redis: Redis.current, key: "fetch:#{@url}", autorelease: 15.minutes.seconds }
   end
 end
index 6e4d6e72ab206118f16dad8abbc3b7e5f736992c..b680c8e961e725d375120c060d6bf00cacd15f68 100644 (file)
@@ -141,6 +141,6 @@ class RemoveStatusService < BaseService
   end
 
   def lock_options
-    { redis: Redis.current, key: "distribute:#{@status.id}" }
+    { redis: Redis.current, key: "distribute:#{@status.id}", autorelease: 5.minutes.seconds }
   end
 end
index 493995447a827704569b77741004488ba5866fad..5400612bfd194f19f0cba9b97b11deec2675f84b 100644 (file)
@@ -146,6 +146,6 @@ class ResolveAccountService < BaseService
   end
 
   def lock_options
-    { redis: Redis.current, key: "resolve:#{@username}@#{@domain}" }
+    { redis: Redis.current, key: "resolve:#{@username}@#{@domain}", autorelease: 15.minutes.seconds }
   end
 end
index 4e20ef31bfc0155054d74f86f316ca83aa688722..e85cd7e95aba70b182ba0220aa1b0e337ec6d363 100644 (file)
@@ -4,7 +4,7 @@ class DistributionWorker
   include Sidekiq::Worker
 
   def perform(status_id)
-    RedisLock.acquire(redis: Redis.current, key: "distribute:#{status_id}") do |lock|
+    RedisLock.acquire(redis: Redis.current, key: "distribute:#{status_id}", autorelease: 5.minutes.seconds) do |lock|
       if lock.acquired?
         FanOutOnWriteService.new.call(Status.find(status_id))
       else