Fix race condition when processing statuses twice with the same idempotency key (#37879)
This commit is contained in:
parent
f7bf804a3f
commit
cff25c186b
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
class PostStatusService < BaseService
|
class PostStatusService < BaseService
|
||||||
include Redisable
|
include Redisable
|
||||||
|
include Lockable
|
||||||
include LanguagesHelper
|
include LanguagesHelper
|
||||||
|
|
||||||
class UnexpectedMentionsError < StandardError
|
class UnexpectedMentionsError < StandardError
|
||||||
@ -39,19 +40,17 @@ class PostStatusService < BaseService
|
|||||||
@in_reply_to = @options[:thread]
|
@in_reply_to = @options[:thread]
|
||||||
@quoted_status = @options[:quoted_status]
|
@quoted_status = @options[:quoted_status]
|
||||||
|
|
||||||
return idempotency_duplicate if idempotency_given? && idempotency_duplicate?
|
with_idempotency do
|
||||||
|
validate_media!
|
||||||
|
preprocess_attributes!
|
||||||
|
|
||||||
validate_media!
|
if scheduled?
|
||||||
preprocess_attributes!
|
schedule_status!
|
||||||
|
else
|
||||||
if scheduled?
|
process_status!
|
||||||
schedule_status!
|
end
|
||||||
else
|
|
||||||
process_status!
|
|
||||||
end
|
end
|
||||||
|
|
||||||
redis.setex(idempotency_key, 3_600, @status.id) if idempotency_given?
|
|
||||||
|
|
||||||
unless scheduled?
|
unless scheduled?
|
||||||
postprocess_status!
|
postprocess_status!
|
||||||
bump_potential_friendship!
|
bump_potential_friendship!
|
||||||
@ -208,6 +207,18 @@ class PostStatusService < BaseService
|
|||||||
@idempotency_duplicate = redis.get(idempotency_key)
|
@idempotency_duplicate = redis.get(idempotency_key)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def with_idempotency
|
||||||
|
return yield unless idempotency_given?
|
||||||
|
|
||||||
|
with_redis_lock("idempotency:lock:status:#{@account.id}:#{@options[:idempotency]}") do
|
||||||
|
return idempotency_duplicate if idempotency_duplicate?
|
||||||
|
|
||||||
|
yield
|
||||||
|
|
||||||
|
redis.setex(idempotency_key, 3_600, @status.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def scheduled_in_the_past?
|
def scheduled_in_the_past?
|
||||||
@scheduled_at.present? && @scheduled_at <= Time.now.utc
|
@scheduled_at.present? && @scheduled_at <= Time.now.utc
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user