First commit
This commit is contained in:
109
backend/internal/service/email_queue_service.go
Normal file
109
backend/internal/service/email_queue_service.go
Normal file
@@ -0,0 +1,109 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// EmailTask 邮件发送任务
|
||||
type EmailTask struct {
|
||||
Email string
|
||||
SiteName string
|
||||
TaskType string // "verify_code"
|
||||
}
|
||||
|
||||
// EmailQueueService 异步邮件队列服务
|
||||
type EmailQueueService struct {
|
||||
emailService *EmailService
|
||||
taskChan chan EmailTask
|
||||
wg sync.WaitGroup
|
||||
stopChan chan struct{}
|
||||
workers int
|
||||
}
|
||||
|
||||
// NewEmailQueueService 创建邮件队列服务
|
||||
func NewEmailQueueService(emailService *EmailService, workers int) *EmailQueueService {
|
||||
if workers <= 0 {
|
||||
workers = 3 // 默认3个工作协程
|
||||
}
|
||||
|
||||
service := &EmailQueueService{
|
||||
emailService: emailService,
|
||||
taskChan: make(chan EmailTask, 100), // 缓冲100个任务
|
||||
stopChan: make(chan struct{}),
|
||||
workers: workers,
|
||||
}
|
||||
|
||||
// 启动工作协程
|
||||
service.start()
|
||||
|
||||
return service
|
||||
}
|
||||
|
||||
// start 启动工作协程
|
||||
func (s *EmailQueueService) start() {
|
||||
for i := 0; i < s.workers; i++ {
|
||||
s.wg.Add(1)
|
||||
go s.worker(i)
|
||||
}
|
||||
log.Printf("[EmailQueue] Started %d workers", s.workers)
|
||||
}
|
||||
|
||||
// worker 工作协程
|
||||
func (s *EmailQueueService) worker(id int) {
|
||||
defer s.wg.Done()
|
||||
|
||||
for {
|
||||
select {
|
||||
case task := <-s.taskChan:
|
||||
s.processTask(id, task)
|
||||
case <-s.stopChan:
|
||||
log.Printf("[EmailQueue] Worker %d stopping", id)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// processTask 处理任务
|
||||
func (s *EmailQueueService) processTask(workerID int, task EmailTask) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
switch task.TaskType {
|
||||
case "verify_code":
|
||||
if err := s.emailService.SendVerifyCode(ctx, task.Email, task.SiteName); err != nil {
|
||||
log.Printf("[EmailQueue] Worker %d failed to send verify code to %s: %v", workerID, task.Email, err)
|
||||
} else {
|
||||
log.Printf("[EmailQueue] Worker %d sent verify code to %s", workerID, task.Email)
|
||||
}
|
||||
default:
|
||||
log.Printf("[EmailQueue] Worker %d unknown task type: %s", workerID, task.TaskType)
|
||||
}
|
||||
}
|
||||
|
||||
// EnqueueVerifyCode 将验证码发送任务加入队列
|
||||
func (s *EmailQueueService) EnqueueVerifyCode(email, siteName string) error {
|
||||
task := EmailTask{
|
||||
Email: email,
|
||||
SiteName: siteName,
|
||||
TaskType: "verify_code",
|
||||
}
|
||||
|
||||
select {
|
||||
case s.taskChan <- task:
|
||||
log.Printf("[EmailQueue] Enqueued verify code task for %s", email)
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("email queue is full")
|
||||
}
|
||||
}
|
||||
|
||||
// Stop 停止队列服务
|
||||
func (s *EmailQueueService) Stop() {
|
||||
close(s.stopChan)
|
||||
s.wg.Wait()
|
||||
log.Println("[EmailQueue] All workers stopped")
|
||||
}
|
||||
Reference in New Issue
Block a user