refactor(app): 优化后台任务退出与外部 IMAP 认证
- 统一用 `WaitGroup` 管理后台 worker,关闭时等待任务结束后再释放数据库连接。 - 将外部 IMAP 的 OAuth 认证切换为 `XOAUTH2` 客户端实现,并补充对应格式测试。 - 调整发送队列的故障恢复逻辑,超时中断后恢复为排队状态以便重新投递。
This commit is contained in:
@@ -15,6 +15,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
@@ -28,6 +29,7 @@ type App struct {
|
||||
now func() time.Time
|
||||
policy *HTMLPolicy
|
||||
workerCancel context.CancelFunc
|
||||
workerWG sync.WaitGroup
|
||||
maildirHealth *maildirSyncHealthTracker
|
||||
externalIMAP externalIMAPClientFactory
|
||||
}
|
||||
@@ -73,16 +75,24 @@ func New(cfg Config, logger *slog.Logger) (*App, error) {
|
||||
}
|
||||
workerCtx, cancel := context.WithCancel(context.Background())
|
||||
a.workerCancel = cancel
|
||||
go a.scheduledSendWorker(workerCtx)
|
||||
a.startWorker(func() { a.scheduledSendWorker(workerCtx) })
|
||||
if strings.TrimSpace(a.cfg.MaildirRoot) != "" {
|
||||
go a.maildirWorker(workerCtx)
|
||||
a.startWorker(func() { a.maildirWorker(workerCtx) })
|
||||
}
|
||||
go a.sendQueueWorker(workerCtx)
|
||||
go a.externalIMAPWorker(workerCtx)
|
||||
go a.smtpEventsCleanupWorker(workerCtx)
|
||||
a.startWorker(func() { a.sendQueueWorker(workerCtx) })
|
||||
a.startWorker(func() { a.externalIMAPWorker(workerCtx) })
|
||||
a.startWorker(func() { a.smtpEventsCleanupWorker(workerCtx) })
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func (a *App) startWorker(fn func()) {
|
||||
a.workerWG.Add(1)
|
||||
go func() {
|
||||
defer a.workerWG.Done()
|
||||
fn()
|
||||
}()
|
||||
}
|
||||
|
||||
func (a *App) Close() error {
|
||||
if a == nil || a.db == nil {
|
||||
return nil
|
||||
@@ -90,6 +100,7 @@ func (a *App) Close() error {
|
||||
if a.workerCancel != nil {
|
||||
a.workerCancel()
|
||||
}
|
||||
a.workerWG.Wait()
|
||||
return a.db.Close()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user