diff --git a/app/workers/admin/distribute_announcement_notification_worker.rb b/app/workers/admin/distribute_announcement_notification_worker.rb index a8b9a0bd94..636852ea1b 100644 --- a/app/workers/admin/distribute_announcement_notification_worker.rb +++ b/app/workers/admin/distribute_announcement_notification_worker.rb @@ -1,15 +1,18 @@ # frozen_string_literal: true class Admin::DistributeAnnouncementNotificationWorker - include Sidekiq::Worker + include Sidekiq::IterableJob + include BulkMailer - def perform(announcement_id) - announcement = Announcement.find(announcement_id) + def build_enumerator(announcement_id, cursor:) + @announcement = Announcement.find(announcement_id) - announcement.scope_for_notification.find_each do |user| - UserMailer.announcement_published(user, announcement).deliver_later! - end + active_record_batches_enumerator(@announcement.scope_for_notification, cursor:) rescue ActiveRecord::RecordNotFound - true + nil + end + + def each_iteration(batch_of_users, _announcement_id) + push_bulk_mailer(UserMailer, :announcement_published, batch_of_users.map { |user| [user, @announcement] }) end end diff --git a/app/workers/admin/distribute_terms_of_service_notification_worker.rb b/app/workers/admin/distribute_terms_of_service_notification_worker.rb index 3e1f651060..5920f1594f 100644 --- a/app/workers/admin/distribute_terms_of_service_notification_worker.rb +++ b/app/workers/admin/distribute_terms_of_service_notification_worker.rb @@ -1,17 +1,22 @@ # frozen_string_literal: true class Admin::DistributeTermsOfServiceNotificationWorker - include Sidekiq::Worker + include Sidekiq::IterableJob + include BulkMailer - def perform(terms_of_service_id) - terms_of_service = TermsOfService.find(terms_of_service_id) + def build_enumerator(terms_of_service_id, cursor:) + @terms_of_service = TermsOfService.find(terms_of_service_id) - terms_of_service.scope_for_interstitial.in_batches.update_all(require_tos_interstitial: true) - - terms_of_service.scope_for_notification.find_each do |user| - UserMailer.terms_of_service_changed(user, terms_of_service).deliver_later! - end + active_record_batches_enumerator(@terms_of_service.scope_for_notification, cursor:) rescue ActiveRecord::RecordNotFound - true + nil + end + + def each_iteration(batch_of_users, _terms_of_service_id) + push_bulk_mailer(UserMailer, :terms_of_service_changed, batch_of_users.map { |user| [user, @terms_of_service] }) + end + + def on_start + @terms_of_service.scope_for_interstitial.in_batches.update_all(require_tos_interstitial: true) end end diff --git a/app/workers/concerns/bulk_mailer.rb b/app/workers/concerns/bulk_mailer.rb new file mode 100644 index 0000000000..78cb3d82bc --- /dev/null +++ b/app/workers/concerns/bulk_mailer.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module BulkMailer + def push_bulk_mailer(mailer_class, mailer_method, args_array) + raise ArgumentError, "No method #{mailer_method} on class #{mailer_class.name}" unless mailer_class.respond_to?(mailer_method) + + job_class = ActionMailer::MailDeliveryJob + + Sidekiq::Client.push_bulk({ + 'class' => ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper, + 'wrapped' => job_class, + 'queue' => mailer_class.deliver_later_queue_name, + 'args' => args_array.map do |args| + [ + job_class.new( + mailer_class.name, + mailer_method.to_s, + 'deliver_now', + args: args + ).serialize, + ] + end, + }) + end +end