diff options
author | Sean McGivern <sean@gitlab.com> | 2016-05-06 13:16:53 +0100 |
---|---|---|
committer | Sean McGivern <sean@gitlab.com> | 2016-05-11 09:16:01 +0100 |
commit | 5f27e26bb4d073c04fd6d3f4116fc1a122db8c00 (patch) | |
tree | a0fea0df79f8e8fae17eb2d5bb1caed099d9b490 /app | |
parent | 48c80fdf43e44ae003753c81a832fc2c0eafdb5d (diff) | |
download | gitlab-ce-5f27e26bb4d073c04fd6d3f4116fc1a122db8c00.tar.gz |
Only generate repository push email once
The repository push email can be very expensive to generate, especially
with syntax-highlighted diffs. Instead of generating the email for each
recipient, generate one email object and reset the Message-Id and To
headers for each recipient. (Cloning would also be expensive in the case
of large emails, although probably not as bad as generating from
scratch.)
Diffstat (limited to 'app')
-rw-r--r-- | app/mailers/emails/projects.rb | 5 | ||||
-rw-r--r-- | app/workers/emails_on_push_worker.rb | 25 |
2 files changed, 23 insertions, 7 deletions
diff --git a/app/mailers/emails/projects.rb b/app/mailers/emails/projects.rb index 377c2999d6c..5489283432b 100644 --- a/app/mailers/emails/projects.rb +++ b/app/mailers/emails/projects.rb @@ -59,9 +59,9 @@ module Emails subject: subject("Project was moved")) end - def repository_push_email(project_id, recipient, opts = {}) + def repository_push_email(project_id, opts = {}) @message = - Gitlab::Email::Message::RepositoryPush.new(self, project_id, recipient, opts) + Gitlab::Email::Message::RepositoryPush.new(self, project_id, opts) # used in notify layout @target_url = @message.target_url @@ -72,7 +72,6 @@ module Emails mail(from: sender(@message.author_id, @message.send_from_committer_email?), reply_to: @message.reply_to, - to: @message.recipient, subject: @message.subject) end end diff --git a/app/workers/emails_on_push_worker.rb b/app/workers/emails_on_push_worker.rb index c4d8595d45d..6ebcba5f39b 100644 --- a/app/workers/emails_on_push_worker.rb +++ b/app/workers/emails_on_push_worker.rb @@ -1,6 +1,8 @@ class EmailsOnPushWorker include Sidekiq::Worker + attr_reader :email, :skip_premailer + def perform(project_id, recipients, push_data, options = {}) options.symbolize_keys! options.reverse_merge!( @@ -41,11 +43,11 @@ class EmailsOnPushWorker end end - recipients.split(" ").each do |recipient| + recipients.split.each do |recipient| begin - Notify.repository_push_email( - project_id, + send_email( recipient, + project_id, author_id: author_id, ref: ref, action: action, @@ -53,14 +55,29 @@ class EmailsOnPushWorker reverse_compare: reverse_compare, send_from_committer_email: send_from_committer_email, disable_diffs: disable_diffs - ).deliver_now + ) + # These are input errors and won't be corrected even if Sidekiq retries rescue Net::SMTPFatalError, Net::SMTPSyntaxError => e logger.info("Failed to send e-mail for project '#{project.name_with_namespace}' to #{recipient}: #{e}") end end ensure + @email = nil compare = nil GC.start end + + private + + def send_email(recipient, project_id, options) + # Generating the body of this email can be expensive, so only do it once + @skip_premailer ||= email.present? + @email ||= Notify.repository_push_email(project_id, options) + + email.to = recipient + email.add_message_id + email.header[:skip_premailer] = true if skip_premailer + email.deliver_now + end end |