diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index 3e4a715225a..5b066523fda 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -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