diff options
author | zeripath <art27@cantab.net> | 2020-01-16 17:55:36 +0000 |
---|---|---|
committer | Antoine GIRARD <sapk@users.noreply.github.com> | 2020-01-16 18:55:36 +0100 |
commit | c76c70a16ce6c1d472059ea3e03206abb5ed884d (patch) | |
tree | 25902cbd062be6fdbefe9417ca33c96acab5809a /services/mailer/mailer.go | |
parent | 06cd3e03a24e23d2d838cda6eb1edd5e7474ad42 (diff) | |
download | gitea-c76c70a16ce6c1d472059ea3e03206abb5ed884d.tar.gz gitea-c76c70a16ce6c1d472059ea3e03206abb5ed884d.zip |
Move mailer to use a queue (#9789)
* Move mailer to use a queue
* Make sectionMap map[string]bool
* Ensure that Message is json encodable
Diffstat (limited to 'services/mailer/mailer.go')
-rw-r--r-- | services/mailer/mailer.go | 90 |
1 files changed, 59 insertions, 31 deletions
diff --git a/services/mailer/mailer.go b/services/mailer/mailer.go index 2e4aa8d71b..afcc7a7278 100644 --- a/services/mailer/mailer.go +++ b/services/mailer/mailer.go @@ -18,7 +18,9 @@ import ( "time" "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/queue" "code.gitea.io/gitea/modules/setting" "github.com/jaytaylor/html2text" @@ -27,38 +29,63 @@ import ( // Message mail body and log info type Message struct { - Info string // Message information for log purpose. - *gomail.Message + Info string // Message information for log purpose. + FromAddress string + FromDisplayName string + To []string + Subject string + Date time.Time + Body string + Headers map[string][]string } -// NewMessageFrom creates new mail message object with custom From header. -func NewMessageFrom(to []string, fromDisplayName, fromAddress, subject, body string) *Message { - log.Trace("NewMessageFrom (body):\n%s", body) - +// ToMessage converts a Message to gomail.Message +func (m *Message) ToMessage() *gomail.Message { msg := gomail.NewMessage() - msg.SetAddressHeader("From", fromAddress, fromDisplayName) - msg.SetHeader("To", to...) + msg.SetAddressHeader("From", m.FromAddress, m.FromDisplayName) + msg.SetHeader("To", m.To...) + for header := range m.Headers { + msg.SetHeader(header, m.Headers[header]...) + } + if len(setting.MailService.SubjectPrefix) > 0 { - msg.SetHeader("Subject", setting.MailService.SubjectPrefix+" "+subject) + msg.SetHeader("Subject", setting.MailService.SubjectPrefix+" "+m.Subject) } else { - msg.SetHeader("Subject", subject) + msg.SetHeader("Subject", m.Subject) } - msg.SetDateHeader("Date", time.Now()) + msg.SetDateHeader("Date", m.Date) msg.SetHeader("X-Auto-Response-Suppress", "All") - plainBody, err := html2text.FromString(body) + plainBody, err := html2text.FromString(m.Body) if err != nil || setting.MailService.SendAsPlainText { - if strings.Contains(base.TruncateString(body, 100), "<html>") { + if strings.Contains(base.TruncateString(m.Body, 100), "<html>") { log.Warn("Mail contains HTML but configured to send as plain text.") } msg.SetBody("text/plain", plainBody) } else { msg.SetBody("text/plain", plainBody) - msg.AddAlternative("text/html", body) + msg.AddAlternative("text/html", m.Body) } + return msg +} + +// SetHeader adds additional headers to a message +func (m *Message) SetHeader(field string, value ...string) { + m.Headers[field] = value +} + +// NewMessageFrom creates new mail message object with custom From header. +func NewMessageFrom(to []string, fromDisplayName, fromAddress, subject, body string) *Message { + log.Trace("NewMessageFrom (body):\n%s", body) return &Message{ - Message: msg, + FromAddress: fromAddress, + FromDisplayName: fromDisplayName, + To: to, + Subject: subject, + Date: time.Now(), + Body: body, + Headers: map[string][]string{}, } } @@ -257,18 +284,7 @@ func (s *dummySender) Send(from string, to []string, msg io.WriterTo) error { return nil } -func processMailQueue() { - for msg := range mailQueue { - log.Trace("New e-mail sending request %s: %s", msg.GetHeader("To"), msg.Info) - if err := gomail.Send(Sender, msg.Message); err != nil { - log.Error("Failed to send emails %s: %s - %v", msg.GetHeader("To"), msg.Info, err) - } else { - log.Trace("E-mails sent %s: %s", msg.GetHeader("To"), msg.Info) - } - } -} - -var mailQueue chan *Message +var mailQueue queue.Queue // Sender sender for sending mail synchronously var Sender gomail.Sender @@ -291,14 +307,26 @@ func NewContext() { Sender = &dummySender{} } - mailQueue = make(chan *Message, setting.MailService.QueueLength) - go processMailQueue() + mailQueue = queue.CreateQueue("mail", func(data ...queue.Data) { + for _, datum := range data { + msg := datum.(*Message) + gomailMsg := msg.ToMessage() + log.Trace("New e-mail sending request %s: %s", gomailMsg.GetHeader("To"), msg.Info) + if err := gomail.Send(Sender, gomailMsg); err != nil { + log.Error("Failed to send emails %s: %s - %v", gomailMsg.GetHeader("To"), msg.Info, err) + } else { + log.Trace("E-mails sent %s: %s", gomailMsg.GetHeader("To"), msg.Info) + } + } + }, &Message{}) + + go graceful.GetManager().RunWithShutdownFns(mailQueue.Run) } // SendAsync send mail asynchronously func SendAsync(msg *Message) { go func() { - mailQueue <- msg + _ = mailQueue.Push(msg) }() } @@ -306,7 +334,7 @@ func SendAsync(msg *Message) { func SendAsyncs(msgs []*Message) { go func() { for _, msg := range msgs { - mailQueue <- msg + _ = mailQueue.Push(msg) } }() } |