mirror of
https://github.com/discourse/discourse.git
synced 2026-08-11 13:35:20 -05:00
FIX: IMAP post alerter race condition and code improvements (#11711)
This PR fixes a race condition with the IMAP notification code. In the `Email::Receiver` we call the `NewPostManager` to create the post and enqueue jobs and sends alerts via `PostAlerter`. However, if the post alerter reaches the `notify_pm_users` and the `group_notifying_via_smtp` method _before_ the incoming email is updated with the post and topic, we unnecessarily send a notification to the person who just posted. The result of this is that the IMAP syncer re-imports the email sent to the user about their own post, which looks like this in the group inbox: To fix this, we skip the jobs enqueued by `NewPostManager` and only enqueue them with `PostJobsEnqueuer` manually _after_ the incoming email record has been updated with the post and topic. Other improvements: * Moved code to calculate email addresses from `IncomingEmail` records into the topic, with a group passed in, for easier testing and debugging. It is not the responsibility of the post alerter to figure this stuff out. * Add shortcut methods on `IncomingEmail` to split or provide an empty array for to and cc addresses to avoid repetition.
This commit is contained in:
@@ -1184,6 +1184,10 @@ module Email
|
||||
options[:post_type] = Post.types[:whisper]
|
||||
end
|
||||
|
||||
# To avoid race conditions with the post alerter and Group SMTP
|
||||
# emails, we skip the jobs here and enqueue them only _after_
|
||||
# the incoming email has been updated with the post and topic.
|
||||
options[:skip_jobs] = true
|
||||
result = NewPostManager.new(user, options).perform
|
||||
|
||||
errors = result.errors.full_messages
|
||||
@@ -1203,6 +1207,13 @@ module Email
|
||||
if result.post.topic&.private_message? && !is_bounce?
|
||||
add_other_addresses(result.post, user)
|
||||
end
|
||||
|
||||
# Alert the people involved in the topic now that the incoming email
|
||||
# has been linked to the post.
|
||||
PostJobsEnqueuer.new(result.post, result.post.topic, options[:topic_id].blank?,
|
||||
import_mode: options[:import_mode],
|
||||
post_alert_options: options[:post_alert_options]
|
||||
).enqueue_jobs
|
||||
end
|
||||
|
||||
result.post
|
||||
|
||||
+2
-2
@@ -309,8 +309,8 @@ module Imap
|
||||
tags = Set.new
|
||||
|
||||
# "Plus" part from the destination email address
|
||||
to_addresses = incoming_email.to_addresses&.split(";") || []
|
||||
cc_addresses = incoming_email.cc_addresses&.split(";") || []
|
||||
to_addresses = incoming_email.to_addresses_split
|
||||
cc_addresses = incoming_email.cc_addresses_split
|
||||
(to_addresses + cc_addresses).each do |address|
|
||||
if plus_part = address&.scan(group_email_regex)&.first&.first
|
||||
tags.add("plus:#{plus_part[1..-1]}") if plus_part.length > 0
|
||||
|
||||
Reference in New Issue
Block a user