diff --git a/exegroup/eghttp/actor.go b/exegroup/eghttp/actor.go index 37e3e02..ead2ee2 100644 --- a/exegroup/eghttp/actor.go +++ b/exegroup/eghttp/actor.go @@ -15,51 +15,73 @@ const ( ) type Option interface { - apply(server *http.Server) + apply(cfg *config) } func WithPort(port int) Option { - return optionFunc(func(server *http.Server) { - server.Addr = net.JoinHostPort("", strconv.Itoa(port)) + return optionFunc(func(cfg *config) { + cfg.server.Addr = net.JoinHostPort("", strconv.Itoa(port)) }) } func WithHandler(handler http.Handler) Option { - return optionFunc(func(server *http.Server) { - server.Handler = handler + return optionFunc(func(cfg *config) { + cfg.server.Handler = handler + }) +} + +func WithServer(server *http.Server) Option { + return optionFunc(func(cfg *config) { + cfg.server = server + }) +} + +func WithStartFn(fn func(server *http.Server) error) Option { + return optionFunc(func(cfg *config) { + cfg.startFn = fn }) } // WithServerOption 使用 fn 配置 [http.Server]; func WithServerOption(fn func(server *http.Server)) Option { - return optionFunc(fn) + return optionFunc(func(cfg *config) { + fn(cfg.server) + }) } -type optionFunc func(server *http.Server) +type config struct { + server *http.Server + startFn func(server *http.Server) error +} -func (fn optionFunc) apply(server *http.Server) { - fn(server) +func newDefaultConfig() *config { + return &config{ + server: &http.Server{ + Addr: DefaultAddr, + ReadHeaderTimeout: DefaultReadHeaderTimeout, + }, + startFn: func(server *http.Server) error { + return server.ListenAndServe() + }, + } +} + +type optionFunc func(cfg *config) + +func (fn optionFunc) apply(cfg *config) { + fn(cfg) } // HTTPListenAndServe 创建 [http.Server] 并提供启动和停止函数; -// opts 按照顺序应用到 [http.Server] 上. func HTTPListenAndServe(opts ...Option) (func(ctx context.Context) error, func(ctx context.Context)) { - server := &http.Server{ - Addr: DefaultAddr, - ReadHeaderTimeout: DefaultReadHeaderTimeout, - } + cfg := newDefaultConfig() for _, opt := range opts { - opt.apply(server) + opt.apply(cfg) } - return HTTPServer(server) -} - -// HTTPServer 提供 [http.Server] 的启动和停止函数; -func HTTPServer(server *http.Server) (func(ctx context.Context) error, func(ctx context.Context)) { inShutdown := &atomic.Bool{} c := make(chan error, 1) goFunc := func(_ context.Context) error { - err := server.ListenAndServe() + err := cfg.startFn(cfg.server) if inShutdown.Load() { err = <-c } @@ -67,7 +89,7 @@ func HTTPServer(server *http.Server) (func(ctx context.Context) error, func(ctx } stopFunc := func(ctx context.Context) { inShutdown.Store(true) - c <- server.Shutdown(ctx) + c <- cfg.server.Shutdown(ctx) } return goFunc, stopFunc }