FIX: Don't rescue PG::UniqueViolation within a transaction.

Also acquire a transaction per link instead of failing when
any of the links can't be processed.

This prevents ActiveRecord from rolling back the transaction
and the next SQL statement sent to PG will fail. This is
however hard to test as it only happens when there are
two competing process trying to process this method at the
same time.
This commit is contained in:
Guo Xiang Tan 2018-10-18 10:52:45 +08:00
parent 732b8655ea
commit 44eba0bb60

View File

@ -112,24 +112,23 @@ SQL
return if post.blank? || post.whisper? return if post.blank? || post.whisper?
added_urls = [] added_urls = []
TopicLink.transaction do reflected_ids = []
added_urls = [] PrettyText
reflected_ids = [] .extract_links(post.cooked)
.map do |u|
PrettyText uri = begin
.extract_links(post.cooked) URI.parse(u.url)
.map do |u| rescue URI::Error
uri = begin
URI.parse(u.url)
rescue URI::Error
end
[u, uri]
end end
.reject { |_, p| p.nil? || "mailto".freeze == p.scheme }
.uniq { |_, p| p } [u, uri]
.each do |link, parsed| end
.reject { |_, p| p.nil? || "mailto".freeze == p.scheme }
.uniq { |_, p| p }
.each do |link, parsed|
TopicLink.transaction do
begin begin
url = link.url url = link.url
internal = false internal = false
@ -185,7 +184,7 @@ SQL
link_post_id: reflected_post.try(:id), link_post_id: reflected_post.try(:id),
quote: link.is_quote, quote: link.is_quote,
extension: file_extension) extension: file_extension)
rescue ActiveRecord::RecordNotUnique, PG::UniqueViolation rescue ActiveRecord::RecordNotUnique
# it's fine # it's fine
end end
end end