fix(notify): waitgroup-based dispatcher shutdown, withoutcancel persist

This commit is contained in:
2026-04-29 11:55:18 +08:00
parent 1e36f21ec4
commit 7377c2135f
2 changed files with 45 additions and 13 deletions
+13 -8
View File
@@ -38,10 +38,11 @@ import (
// App 持有运行期所有需要被关停的资源。字段保持非导出,避免外部直接操作。
type App struct {
cfg *config.Config
log *slog.Logger
pool *db.Pool
server *http.Server
cfg *config.Config
log *slog.Logger
pool *db.Pool
server *http.Server
dispatcher *notify.Dispatcher
}
// New 把所有模块按启动顺序拼装好。任何阶段失败都会返回错误,不留半成品资源。
@@ -68,9 +69,6 @@ func New(ctx context.Context, cfg *config.Config, dist embed.FS) (*App, error) {
notifyRepo := notify.NewPostgresRepository(pool)
notifyDispatcher := notify.NewDispatcher(notifyRepo, log)
notifyDispatcher.Register(notify.NewDummyNotifier(log))
// 当前 dispatcher 仅暴露给本包:未来引入定时任务/后台 worker 才需把它
// 通过 App 字段透出去,目前保留局部变量以避免暴露未稳定 API。
_ = notifyDispatcher
spaSub, err := fs.Sub(dist, "web/dist")
if err != nil {
@@ -113,7 +111,7 @@ func New(ctx context.Context, cfg *config.Config, dist embed.FS) (*App, error) {
WriteTimeout: 60 * time.Second,
IdleTimeout: 120 * time.Second,
}
return &App{cfg: cfg, log: log, pool: pool, server: srv}, nil
return &App{cfg: cfg, log: log, pool: pool, server: srv, dispatcher: notifyDispatcher}, nil
}
// Run 启动 HTTP server 并阻塞直到 ctx 取消(Shutdown)或服务器报错。
@@ -137,9 +135,16 @@ func (a *App) Run(ctx context.Context) error {
if shutErr != nil {
a.log.Error("server shutdown", "err", shutErr.Error())
}
// server 已停止接收新请求;等异步通知投递结束再关 pool
if err := a.dispatcher.Shutdown(shutCtx); err != nil {
a.log.Warn("notify dispatcher drain", "err", err.Error())
}
a.pool.Close()
return shutErr
case err := <-errCh:
drainCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
_ = a.dispatcher.Shutdown(drainCtx)
a.pool.Close()
return err
}