@@ -18,7 +18,9 @@ import (
1818 "time"
1919
2020 "code.gitea.io/gitea/modules/base"
21+ "code.gitea.io/gitea/modules/graceful"
2122 "code.gitea.io/gitea/modules/log"
23+ "code.gitea.io/gitea/modules/queue"
2224 "code.gitea.io/gitea/modules/setting"
2325
2426 "github.com/jaytaylor/html2text"
@@ -27,38 +29,63 @@ import (
2729
2830// Message mail body and log info
2931type Message struct {
30- Info string // Message information for log purpose.
31- * gomail.Message
32+ Info string // Message information for log purpose.
33+ FromAddress string
34+ FromDisplayName string
35+ To []string
36+ Subject string
37+ Date time.Time
38+ Body string
39+ Headers map [string ][]string
3240}
3341
34- // NewMessageFrom creates new mail message object with custom From header.
35- func NewMessageFrom (to []string , fromDisplayName , fromAddress , subject , body string ) * Message {
36- log .Trace ("NewMessageFrom (body):\n %s" , body )
37-
42+ // ToMessage converts a Message to gomail.Message
43+ func (m * Message ) ToMessage () * gomail.Message {
3844 msg := gomail .NewMessage ()
39- msg .SetAddressHeader ("From" , fromAddress , fromDisplayName )
40- msg .SetHeader ("To" , to ... )
45+ msg .SetAddressHeader ("From" , m .FromAddress , m .FromDisplayName )
46+ msg .SetHeader ("To" , m .To ... )
47+ for header := range m .Headers {
48+ msg .SetHeader (header , m .Headers [header ]... )
49+ }
50+
4151 if len (setting .MailService .SubjectPrefix ) > 0 {
42- msg .SetHeader ("Subject" , setting .MailService .SubjectPrefix + " " + subject )
52+ msg .SetHeader ("Subject" , setting .MailService .SubjectPrefix + " " + m . Subject )
4353 } else {
44- msg .SetHeader ("Subject" , subject )
54+ msg .SetHeader ("Subject" , m . Subject )
4555 }
46- msg .SetDateHeader ("Date" , time . Now () )
56+ msg .SetDateHeader ("Date" , m . Date )
4757 msg .SetHeader ("X-Auto-Response-Suppress" , "All" )
4858
49- plainBody , err := html2text .FromString (body )
59+ plainBody , err := html2text .FromString (m . Body )
5060 if err != nil || setting .MailService .SendAsPlainText {
51- if strings .Contains (base .TruncateString (body , 100 ), "<html>" ) {
61+ if strings .Contains (base .TruncateString (m . Body , 100 ), "<html>" ) {
5262 log .Warn ("Mail contains HTML but configured to send as plain text." )
5363 }
5464 msg .SetBody ("text/plain" , plainBody )
5565 } else {
5666 msg .SetBody ("text/plain" , plainBody )
57- msg .AddAlternative ("text/html" , body )
67+ msg .AddAlternative ("text/html" , m . Body )
5868 }
69+ return msg
70+ }
71+
72+ // SetHeader adds additional headers to a message
73+ func (m * Message ) SetHeader (field string , value ... string ) {
74+ m .Headers [field ] = value
75+ }
76+
77+ // NewMessageFrom creates new mail message object with custom From header.
78+ func NewMessageFrom (to []string , fromDisplayName , fromAddress , subject , body string ) * Message {
79+ log .Trace ("NewMessageFrom (body):\n %s" , body )
5980
6081 return & Message {
61- Message : msg ,
82+ FromAddress : fromAddress ,
83+ FromDisplayName : fromDisplayName ,
84+ To : to ,
85+ Subject : subject ,
86+ Date : time .Now (),
87+ Body : body ,
88+ Headers : map [string ][]string {},
6289 }
6390}
6491
@@ -257,18 +284,7 @@ func (s *dummySender) Send(from string, to []string, msg io.WriterTo) error {
257284 return nil
258285}
259286
260- func processMailQueue () {
261- for msg := range mailQueue {
262- log .Trace ("New e-mail sending request %s: %s" , msg .GetHeader ("To" ), msg .Info )
263- if err := gomail .Send (Sender , msg .Message ); err != nil {
264- log .Error ("Failed to send emails %s: %s - %v" , msg .GetHeader ("To" ), msg .Info , err )
265- } else {
266- log .Trace ("E-mails sent %s: %s" , msg .GetHeader ("To" ), msg .Info )
267- }
268- }
269- }
270-
271- var mailQueue chan * Message
287+ var mailQueue queue.Queue
272288
273289// Sender sender for sending mail synchronously
274290var Sender gomail.Sender
@@ -291,22 +307,34 @@ func NewContext() {
291307 Sender = & dummySender {}
292308 }
293309
294- mailQueue = make (chan * Message , setting .MailService .QueueLength )
295- go processMailQueue ()
310+ mailQueue = queue .CreateQueue ("mail" , func (data ... queue.Data ) {
311+ for _ , datum := range data {
312+ msg := datum .(* Message )
313+ gomailMsg := msg .ToMessage ()
314+ log .Trace ("New e-mail sending request %s: %s" , gomailMsg .GetHeader ("To" ), msg .Info )
315+ if err := gomail .Send (Sender , gomailMsg ); err != nil {
316+ log .Error ("Failed to send emails %s: %s - %v" , gomailMsg .GetHeader ("To" ), msg .Info , err )
317+ } else {
318+ log .Trace ("E-mails sent %s: %s" , gomailMsg .GetHeader ("To" ), msg .Info )
319+ }
320+ }
321+ }, & Message {})
322+
323+ go graceful .GetManager ().RunWithShutdownFns (mailQueue .Run )
296324}
297325
298326// SendAsync send mail asynchronously
299327func SendAsync (msg * Message ) {
300328 go func () {
301- mailQueue <- msg
329+ _ = mailQueue . Push ( msg )
302330 }()
303331}
304332
305333// SendAsyncs send mails asynchronously
306334func SendAsyncs (msgs []* Message ) {
307335 go func () {
308336 for _ , msg := range msgs {
309- mailQueue <- msg
337+ _ = mailQueue . Push ( msg )
310338 }
311339 }()
312340}
0 commit comments