From c82211c957dab0fe37eaf8eb3a6cdc2056217673 Mon Sep 17 00:00:00 2001 From: Ge Song Date: Tue, 27 Jun 2023 11:13:24 +0800 Subject: [PATCH] =?UTF-8?q?exegroup/HTTPListenAndServe=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E5=88=B0eghttp=E5=B9=B6=E5=A2=9E=E5=8A=A0HTTPServer=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- exegroup/eghttp/actor.go | 73 ++++++++++++++++++++++++++++++++++++++++ exegroup/httpserver.go | 33 ------------------ 2 files changed, 73 insertions(+), 33 deletions(-) create mode 100644 exegroup/eghttp/actor.go delete mode 100644 exegroup/httpserver.go diff --git a/exegroup/eghttp/actor.go b/exegroup/eghttp/actor.go new file mode 100644 index 0000000..37e3e02 --- /dev/null +++ b/exegroup/eghttp/actor.go @@ -0,0 +1,73 @@ +package eghttp + +import ( + "context" + "net" + "net/http" + "strconv" + "sync/atomic" + "time" +) + +const ( + DefaultAddr = ":8080" + DefaultReadHeaderTimeout = time.Second +) + +type Option interface { + apply(server *http.Server) +} + +func WithPort(port int) Option { + return optionFunc(func(server *http.Server) { + server.Addr = net.JoinHostPort("", strconv.Itoa(port)) + }) +} + +func WithHandler(handler http.Handler) Option { + return optionFunc(func(server *http.Server) { + server.Handler = handler + }) +} + +// WithServerOption 使用 fn 配置 [http.Server]; +func WithServerOption(fn func(server *http.Server)) Option { + return optionFunc(fn) +} + +type optionFunc func(server *http.Server) + +func (fn optionFunc) apply(server *http.Server) { + fn(server) +} + +// 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, + } + for _, opt := range opts { + opt.apply(server) + } + 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() + if inShutdown.Load() { + err = <-c + } + return err + } + stopFunc := func(ctx context.Context) { + inShutdown.Store(true) + c <- server.Shutdown(ctx) + } + return goFunc, stopFunc +} diff --git a/exegroup/httpserver.go b/exegroup/httpserver.go deleted file mode 100644 index aee7f18..0000000 --- a/exegroup/httpserver.go +++ /dev/null @@ -1,33 +0,0 @@ -package exegroup - -import ( - "context" - "net" - "net/http" - "strconv" - "sync/atomic" - "time" -) - -// HTTPListenAndServe 提供 [http.Server] 的启动和停止函数; -func HTTPListenAndServe(port int, handler http.Handler) (func(ctx context.Context) error, func(ctx context.Context)) { - server := &http.Server{ - Addr: net.JoinHostPort("", strconv.Itoa(port)), - Handler: handler, - ReadHeaderTimeout: time.Second, - } - inShutdown := &atomic.Bool{} - c := make(chan error, 1) - goFunc := func(_ context.Context) error { - err := server.ListenAndServe() - if inShutdown.Load() { - err = <-c - } - return err - } - stopFunc := func(ctx context.Context) { - inShutdown.Store(true) - c <- server.Shutdown(ctx) - } - return goFunc, stopFunc -}