Fix some RedisLocks auto-releasing too fast (#16276)
* 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 timeoutpull/1542/head
parent
028ba13eb3
commit
9a19227f17
|
@ -216,8 +216,8 @@ class ActivityPub::Activity
|
||||||
redis.del(key)
|
redis.del(key)
|
||||||
end
|
end
|
||||||
|
|
||||||
def lock_or_fail(key)
|
def lock_or_fail(key, expire_after = 15.minutes.seconds)
|
||||||
RedisLock.acquire({ redis: Redis.current, key: key }) do |lock|
|
RedisLock.acquire({ redis: Redis.current, key: key, autorelease: expire_after }) do |lock|
|
||||||
if lock.acquired?
|
if lock.acquired?
|
||||||
yield
|
yield
|
||||||
else
|
else
|
||||||
|
|
|
@ -290,7 +290,7 @@ class ActivityPub::ProcessAccountService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
def lock_options
|
def lock_options
|
||||||
{ redis: Redis.current, key: "process_account:#{@uri}" }
|
{ redis: Redis.current, key: "process_account:#{@uri}", autorelease: 15.minutes.seconds }
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_tags
|
def process_tags
|
||||||
|
|
|
@ -175,6 +175,6 @@ class FetchLinkCardService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
def lock_options
|
def lock_options
|
||||||
{ redis: Redis.current, key: "fetch:#{@url}" }
|
{ redis: Redis.current, key: "fetch:#{@url}", autorelease: 15.minutes.seconds }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -141,6 +141,6 @@ class RemoveStatusService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
def lock_options
|
def lock_options
|
||||||
{ redis: Redis.current, key: "distribute:#{@status.id}" }
|
{ redis: Redis.current, key: "distribute:#{@status.id}", autorelease: 5.minutes.seconds }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -146,6 +146,6 @@ class ResolveAccountService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
def lock_options
|
def lock_options
|
||||||
{ redis: Redis.current, key: "resolve:#{@username}@#{@domain}" }
|
{ redis: Redis.current, key: "resolve:#{@username}@#{@domain}", autorelease: 15.minutes.seconds }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,7 @@ class DistributionWorker
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
|
|
||||||
def perform(status_id)
|
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?
|
if lock.acquired?
|
||||||
FanOutOnWriteService.new.call(Status.find(status_id))
|
FanOutOnWriteService.new.call(Status.find(status_id))
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue