Move network calls out of transaction in ActivityPub handler (#8951)
Mention and emoji code may perform network calls, but does not need to do that inside the database transaction. This may improve availability of database connections when using pgBouncer in transaction mode.
This commit is contained in:
parent
ac7df62a04
commit
790d3bc637
1 changed files with 50 additions and 31 deletions
|
@ -22,12 +22,16 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
private
|
||||
|
||||
def process_status
|
||||
status_params = process_status_params
|
||||
@tags = []
|
||||
@mentions = []
|
||||
@params = {}
|
||||
|
||||
process_status_params
|
||||
process_tags
|
||||
|
||||
ApplicationRecord.transaction do
|
||||
@status = Status.create!(status_params)
|
||||
|
||||
process_tags(@status)
|
||||
@status = Status.create!(@params)
|
||||
attach_tags(@status)
|
||||
end
|
||||
|
||||
resolve_thread(@status)
|
||||
|
@ -42,62 +46,77 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
end
|
||||
|
||||
def process_status_params
|
||||
{
|
||||
uri: @object['id'],
|
||||
url: object_url || @object['id'],
|
||||
account: @account,
|
||||
text: text_from_content || '',
|
||||
language: detected_language,
|
||||
spoiler_text: text_from_summary || '',
|
||||
created_at: @object['published'],
|
||||
override_timestamps: @options[:override_timestamps],
|
||||
reply: @object['inReplyTo'].present?,
|
||||
sensitive: @object['sensitive'] || false,
|
||||
visibility: visibility_from_audience,
|
||||
thread: replied_to_status,
|
||||
conversation: conversation_from_uri(@object['conversation']),
|
||||
media_attachment_ids: process_attachments.take(4).map(&:id),
|
||||
}
|
||||
@params = begin
|
||||
{
|
||||
uri: @object['id'],
|
||||
url: object_url || @object['id'],
|
||||
account: @account,
|
||||
text: text_from_content || '',
|
||||
language: detected_language,
|
||||
spoiler_text: text_from_summary || '',
|
||||
created_at: @object['published'],
|
||||
override_timestamps: @options[:override_timestamps],
|
||||
reply: @object['inReplyTo'].present?,
|
||||
sensitive: @object['sensitive'] || false,
|
||||
visibility: visibility_from_audience,
|
||||
thread: replied_to_status,
|
||||
conversation: conversation_from_uri(@object['conversation']),
|
||||
media_attachment_ids: process_attachments.take(4).map(&:id),
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def process_tags(status)
|
||||
def attach_tags(status)
|
||||
@tags.each do |tag|
|
||||
status.tags << tag
|
||||
TrendingTags.record_use!(hashtag, status.account, status.created_at) if status.public_visibility?
|
||||
end
|
||||
|
||||
@mentions.each do |mention|
|
||||
mention.status = status
|
||||
mention.save
|
||||
end
|
||||
end
|
||||
|
||||
def process_tags
|
||||
return if @object['tag'].nil?
|
||||
|
||||
as_array(@object['tag']).each do |tag|
|
||||
if equals_or_includes?(tag['type'], 'Hashtag')
|
||||
process_hashtag tag, status
|
||||
process_hashtag tag
|
||||
elsif equals_or_includes?(tag['type'], 'Mention')
|
||||
process_mention tag, status
|
||||
process_mention tag
|
||||
elsif equals_or_includes?(tag['type'], 'Emoji')
|
||||
process_emoji tag, status
|
||||
process_emoji tag
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def process_hashtag(tag, status)
|
||||
def process_hashtag(tag)
|
||||
return if tag['name'].blank?
|
||||
|
||||
hashtag = tag['name'].gsub(/\A#/, '').mb_chars.downcase
|
||||
hashtag = Tag.where(name: hashtag).first_or_create(name: hashtag)
|
||||
|
||||
return if status.tags.include?(hashtag)
|
||||
return if @tags.include?(hashtag)
|
||||
|
||||
status.tags << hashtag
|
||||
TrendingTags.record_use!(hashtag, status.account, status.created_at) if status.public_visibility?
|
||||
@tags << hashtag
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
nil
|
||||
end
|
||||
|
||||
def process_mention(tag, status)
|
||||
def process_mention(tag)
|
||||
return if tag['href'].blank?
|
||||
|
||||
account = account_from_uri(tag['href'])
|
||||
account = ::FetchRemoteAccountService.new.call(tag['href'], id: false) if account.nil?
|
||||
|
||||
return if account.nil?
|
||||
account.mentions.create(status: status)
|
||||
|
||||
@mentions << Mention.new(account: account)
|
||||
end
|
||||
|
||||
def process_emoji(tag, _status)
|
||||
def process_emoji(tag)
|
||||
return if skip_download?
|
||||
return if tag['name'].blank? || tag['icon'].blank? || tag['icon']['url'].blank?
|
||||
|
||||
|
|
Loading…
Reference in a new issue