forked from cybrespace/mastodon
Fix race condition when processing incoming OStatus messages (#5013)
* Avoid races in incoming OStatus toots processing * oops * oops again
This commit is contained in:
parent
bb4d005a83
commit
34fa305a00
|
@ -14,14 +14,22 @@ class OStatus::Activity::Creation < OStatus::Activity::Base
|
||||||
return result if result.first.present?
|
return result if result.first.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
RedisLock.acquire(lock_options) do |lock|
|
||||||
|
if lock.acquired?
|
||||||
|
# Return early if status already exists in db
|
||||||
|
@status = find_status(id)
|
||||||
|
return [@status, false] unless @status.nil?
|
||||||
|
@status = process_status
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
[@status, true]
|
||||||
|
end
|
||||||
|
|
||||||
|
def process_status
|
||||||
Rails.logger.debug "Creating remote status #{id}"
|
Rails.logger.debug "Creating remote status #{id}"
|
||||||
|
|
||||||
# Return early if status already exists in db
|
|
||||||
status = find_status(id)
|
|
||||||
|
|
||||||
return [status, false] unless status.nil?
|
|
||||||
|
|
||||||
cached_reblog = reblog
|
cached_reblog = reblog
|
||||||
|
status = nil
|
||||||
|
|
||||||
ApplicationRecord.transaction do
|
ApplicationRecord.transaction do
|
||||||
status = Status.create!(
|
status = Status.create!(
|
||||||
|
@ -55,7 +63,7 @@ class OStatus::Activity::Creation < OStatus::Activity::Base
|
||||||
LinkCrawlWorker.perform_async(status.id) unless status.spoiler_text?
|
LinkCrawlWorker.perform_async(status.id) unless status.spoiler_text?
|
||||||
DistributionWorker.perform_async(status.id)
|
DistributionWorker.perform_async(status.id)
|
||||||
|
|
||||||
[status, true]
|
status
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform_via_activitypub
|
def perform_via_activitypub
|
||||||
|
@ -179,4 +187,8 @@ class OStatus::Activity::Creation < OStatus::Activity::Base
|
||||||
Account.where(uri: href).or(Account.where(url: href)).first || FetchRemoteAccountService.new.call(href)
|
Account.where(uri: href).or(Account.where(url: href)).first || FetchRemoteAccountService.new.call(href)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def lock_options
|
||||||
|
{ redis: Redis.current, key: "create:#{id}" }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue