mirror of
https://github.com/discourse/discourse.git
synced 2025-03-05 02:39:26 +00:00
Use the `sidekiq_retry_in` code from Jobs::UserEmail in group SMTP. Also we don't need to keep `seconds_to_delay` -- sidekiq uses the default delay calculation if you return 0 or nil from the block. See3330df0ee3/lib/sidekiq/job_retry.rb (L216-L234)
for sidekiq default retry delay logic. I experimented with extracting this into a concern or a module, but `sidekiq_retry_in` is quite magic and it would not allow me to abstract away into a module that calls some method specificall in the child job class. I would love to write tests for this, but it does not seem possible (not sure if its because of our test setup) to write tests that test sidekiq's retry capability, and I am not sure if we should be anyway. Initial addition to UserEmail did not test this functionalityd224966a0e
126 lines
4.2 KiB
Ruby
126 lines
4.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Jobs
|
|
|
|
class NotifyMailingListSubscribers < ::Jobs::Base
|
|
include Skippable
|
|
|
|
RETRY_TIMES = [5.minute, 15.minute, 30.minute, 45.minute, 90.minute, 180.minute, 300.minute]
|
|
|
|
sidekiq_options queue: 'low'
|
|
|
|
sidekiq_options retry: RETRY_TIMES.size
|
|
|
|
sidekiq_retry_in do |count, exception|
|
|
# returning nil/0 will trigger the default sidekiq
|
|
# retry formula
|
|
#
|
|
# See https://github.com/mperham/sidekiq/blob/3330df0ee37cfd3e0cd3ef01e3e66b584b99d488/lib/sidekiq/job_retry.rb#L216-L234
|
|
case exception.wrapped
|
|
when SocketError
|
|
return RETRY_TIMES[count]
|
|
end
|
|
end
|
|
|
|
def execute(args)
|
|
return if SiteSetting.disable_mailing_list_mode
|
|
|
|
post_id = args[:post_id]
|
|
post = post_id ? Post.with_deleted.find_by(id: post_id) : nil
|
|
|
|
return if !post || post.trashed? || post.user_deleted? || !post.topic || post.raw.blank?
|
|
|
|
users =
|
|
User.activated.not_silenced.not_suspended.real
|
|
.joins(:user_option)
|
|
.where('user_options.mailing_list_mode AND user_options.mailing_list_mode_frequency > 0')
|
|
.where('NOT EXISTS (
|
|
SELECT 1
|
|
FROM muted_users mu
|
|
WHERE mu.muted_user_id = ? AND mu.user_id = users.id
|
|
)', post.user_id)
|
|
.where('NOT EXISTS (
|
|
SELECT 1
|
|
FROM ignored_users iu
|
|
WHERE iu.ignored_user_id = ? AND iu.user_id = users.id
|
|
)', post.user_id)
|
|
.where('NOT EXISTS (
|
|
SELECT 1
|
|
FROM topic_users tu
|
|
WHERE tu.topic_id = ? AND tu.user_id = users.id AND tu.notification_level = ?
|
|
)', post.topic_id, TopicUser.notification_levels[:muted])
|
|
.where('NOT EXISTS (
|
|
SELECT 1
|
|
FROM category_users cu
|
|
WHERE cu.category_id = ? AND cu.user_id = users.id AND cu.notification_level = ?
|
|
)', post.topic.category_id, CategoryUser.notification_levels[:muted])
|
|
|
|
if SiteSetting.tagging_enabled?
|
|
users = users.where('NOT EXISTS (
|
|
SELECT 1
|
|
FROM tag_users tu
|
|
WHERE tu.tag_id in (:tag_ids) AND tu.user_id = users.id AND tu.notification_level = :muted
|
|
)', tag_ids: post.topic.tag_ids, muted: TagUser.notification_levels[:muted])
|
|
end
|
|
|
|
if SiteSetting.must_approve_users
|
|
users = users.where(approved: true)
|
|
end
|
|
|
|
if SiteSetting.mute_all_categories_by_default
|
|
users = users.watching_topic_when_mute_categories_by_default(post.topic)
|
|
end
|
|
|
|
DiscourseEvent.trigger(:notify_mailing_list_subscribers, users, post)
|
|
users.find_each do |user|
|
|
if Guardian.new(user).can_see?(post)
|
|
if EmailLog.reached_max_emails?(user)
|
|
skip(user.email, user.id, post.id,
|
|
SkippedEmailLog.reason_types[:exceeded_emails_limit]
|
|
)
|
|
|
|
next
|
|
end
|
|
|
|
if user.user_stat.bounce_score >= SiteSetting.bounce_score_threshold
|
|
skip(user.email, user.id, post.id,
|
|
SkippedEmailLog.reason_types[:exceeded_bounces_limit]
|
|
)
|
|
|
|
next
|
|
end
|
|
|
|
if (user.id == post.user_id) && (user.user_option.mailing_list_mode_frequency == 2)
|
|
skip(user.email, user.id, post.id,
|
|
SkippedEmailLog.reason_types[:mailing_list_no_echo_mode]
|
|
)
|
|
|
|
next
|
|
end
|
|
|
|
begin
|
|
if message = UserNotifications.mailing_list_notify(user, post)
|
|
EmailLog.unique_email_per_post(post, user) do
|
|
Email::Sender.new(message, :mailing_list, user).send
|
|
end
|
|
end
|
|
rescue => e
|
|
Discourse.handle_job_exception(e, error_context(args, "Sending post to mailing list subscribers", user_id: user.id, user_email: user.email))
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
def skip(to_address, user_id, post_id, reason_type)
|
|
create_skipped_email_log(
|
|
email_type: 'mailing_list',
|
|
to_address: to_address,
|
|
user_id: user_id,
|
|
post_id: post_id,
|
|
reason_type: reason_type
|
|
)
|
|
end
|
|
end
|
|
end
|