mirror of
https://github.com/mastodon/mastodon.git
synced 2026-03-21 18:05:23 -05:00
Fix race condition when processing statuses twice with the same idempotency key (#37879)
Some checks are pending
Check i18n / check-i18n (push) Waiting to run
Chromatic / Check for relevant changes (push) Waiting to run
Chromatic / Run Chromatic (push) Blocked by required conditions
CodeQL / Analyze (actions) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (ruby) (push) Waiting to run
Crowdin / Upload translations / upload-translations (push) Waiting to run
Check formatting / lint (push) Waiting to run
CSS Linting / lint (push) Waiting to run
JavaScript Linting / lint (push) Waiting to run
Ruby Linting / lint (push) Waiting to run
JavaScript Testing / test (push) Waiting to run
Historical data migration test / test (14-alpine) (push) Waiting to run
Historical data migration test / test (15-alpine) (push) Waiting to run
Historical data migration test / test (16-alpine) (push) Waiting to run
Historical data migration test / test (17-alpine) (push) Waiting to run
Ruby Testing / build (production) (push) Waiting to run
Ruby Testing / build (test) (push) Waiting to run
Ruby Testing / test (.ruby-version) (push) Blocked by required conditions
Ruby Testing / test (3.2) (push) Blocked by required conditions
Ruby Testing / test (3.3) (push) Blocked by required conditions
Ruby Testing / End to End testing (.ruby-version) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.2) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.3) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Some checks are pending
Check i18n / check-i18n (push) Waiting to run
Chromatic / Check for relevant changes (push) Waiting to run
Chromatic / Run Chromatic (push) Blocked by required conditions
CodeQL / Analyze (actions) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (ruby) (push) Waiting to run
Crowdin / Upload translations / upload-translations (push) Waiting to run
Check formatting / lint (push) Waiting to run
CSS Linting / lint (push) Waiting to run
JavaScript Linting / lint (push) Waiting to run
Ruby Linting / lint (push) Waiting to run
JavaScript Testing / test (push) Waiting to run
Historical data migration test / test (14-alpine) (push) Waiting to run
Historical data migration test / test (15-alpine) (push) Waiting to run
Historical data migration test / test (16-alpine) (push) Waiting to run
Historical data migration test / test (17-alpine) (push) Waiting to run
Ruby Testing / build (production) (push) Waiting to run
Ruby Testing / build (test) (push) Waiting to run
Ruby Testing / test (.ruby-version) (push) Blocked by required conditions
Ruby Testing / test (3.2) (push) Blocked by required conditions
Ruby Testing / test (3.3) (push) Blocked by required conditions
Ruby Testing / End to End testing (.ruby-version) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.2) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.3) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
This commit is contained in:
parent
f7bf804a3f
commit
cff25c186b
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user