Fix race condition when processing statuses twice with the same idempotency key (#37879)

This commit is contained in:
Claire 2026-02-16 15:58:22 +01:00 committed by GitHub
parent f7bf804a3f
commit cff25c186b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -2,6 +2,7 @@
class PostStatusService < BaseService
include Redisable
include Lockable
include LanguagesHelper
class UnexpectedMentionsError < StandardError
@ -39,19 +40,17 @@ class PostStatusService < BaseService
@in_reply_to = @options[:thread]
@quoted_status = @options[:quoted_status]
return idempotency_duplicate if idempotency_given? && idempotency_duplicate?
with_idempotency do
validate_media!
preprocess_attributes!
validate_media!
preprocess_attributes!
if scheduled?
schedule_status!
else
process_status!
if scheduled?
schedule_status!
else
process_status!
end
end
redis.setex(idempotency_key, 3_600, @status.id) if idempotency_given?
unless scheduled?
postprocess_status!
bump_potential_friendship!
@ -208,6 +207,18 @@ class PostStatusService < BaseService
@idempotency_duplicate = redis.get(idempotency_key)
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?
@scheduled_at.present? && @scheduled_at <= Time.now.utc
end