gitea源码

mailer.go 2.4KB

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