1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
// Copyright 2014 The Gogs Authors. All rights reserved.
// Copyright 2017 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package mailer
import (
"context"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/queue"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/templates"
sender_service "code.gitea.io/gitea/services/mailer/sender"
notify_service "code.gitea.io/gitea/services/notify"
)
var mailQueue *queue.WorkerPoolQueue[*sender_service.Message]
// sender sender for sending mail synchronously
var sender sender_service.Sender
// NewContext start mail queue service
func NewContext(ctx context.Context) {
// Need to check if mailQueue is nil because in during reinstall (user had installed
// before but switched install lock off), this function will be called again
// while mail queue is already processing tasks, and produces a race condition.
if setting.MailService == nil || mailQueue != nil {
return
}
if setting.Service.EnableNotifyMail {
notify_service.RegisterNotifier(NewNotifier())
}
switch setting.MailService.Protocol {
case "sendmail":
sender = &sender_service.SendmailSender{}
case "dummy":
sender = &sender_service.DummySender{}
default:
sender = &sender_service.SMTPSender{}
}
subjectTemplates, bodyTemplates = templates.Mailer(ctx)
mailQueue = queue.CreateSimpleQueue(graceful.GetManager().ShutdownContext(), "mail", func(items ...*sender_service.Message) []*sender_service.Message {
for _, msg := range items {
gomailMsg := msg.ToMessage()
log.Trace("New e-mail sending request %s: %s", gomailMsg.GetGenHeader("To"), msg.Info)
if err := sender_service.Send(sender, msg); err != nil {
log.Error("Failed to send emails %s: %s - %v", gomailMsg.GetGenHeader("To"), msg.Info, err)
} else {
log.Trace("E-mails sent %s: %s", gomailMsg.GetGenHeader("To"), msg.Info)
}
}
return nil
})
if mailQueue == nil {
log.Fatal("Unable to create mail queue")
}
go graceful.GetManager().RunWithCancel(mailQueue)
}
// SendAsync send emails asynchronously (make it mockable)
var SendAsync = sendAsync
func sendAsync(msgs ...*sender_service.Message) {
if setting.MailService == nil {
log.Error("Mailer: SendAsync is being invoked but mail service hasn't been initialized")
return
}
go func() {
for _, msg := range msgs {
_ = mailQueue.Push(msg)
}
}()
}
|