refactor(app): 优化后台任务退出与外部 IMAP 认证

- 统一用 `WaitGroup` 管理后台 worker,关闭时等待任务结束后再释放数据库连接。
- 将外部 IMAP 的 OAuth 认证切换为 `XOAUTH2` 客户端实现,并补充对应格式测试。
- 调整发送队列的故障恢复逻辑,超时中断后恢复为排队状态以便重新投递。
This commit is contained in:
LanQin
2026-06-25 21:36:59 +08:00
parent 081cfad02d
commit efcdc691de
4 changed files with 66 additions and 9 deletions
+8 -2
View File
@@ -126,6 +126,12 @@ func (a *App) sendQueueWorker(ctx context.Context) {
ticker := time.NewTicker(10 * time.Second)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
a.log.Info("send queue worker stopped")
return
default:
}
if err := a.processDueSendQueue(ctx); err != nil {
a.log.Warn("send queue worker failed", "error", err)
}
@@ -232,12 +238,12 @@ func (a *App) recoverStaleSendQueueItems(ctx context.Context) error {
}
continue
}
res, err := a.db.ExecContext(ctx, `UPDATE send_queue SET status=?,next_attempt_at=?,last_error=?,updated_at=? WHERE id=? AND status=?`, sendQueueStatusFailed, now, "send attempt interrupted", now, item.ID, sendQueueStatusSending)
res, err := a.db.ExecContext(ctx, `UPDATE send_queue SET status=?,next_attempt_at=?,last_error=?,updated_at=? WHERE id=? AND status=?`, sendQueueStatusQueued, now, "send attempt interrupted", now, item.ID, sendQueueStatusSending)
if err != nil {
return err
}
if n, _ := res.RowsAffected(); n > 0 {
a.recordSendAudit(ctx, sendAuditRetry, sendQueueStatusFailed, sendAuditInputFromQueue(item, "send attempt interrupted"))
a.recordSendAudit(ctx, sendAuditRetry, sendQueueStatusQueued, sendAuditInputFromQueue(item, "send attempt interrupted"))
}
}
return nil