You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
3.9 KiB
Go

package nnet
import (
"net/http"
"github.com/noahlann/nnet/pkg/config"
routerpkg "github.com/noahlann/nnet/pkg/router"
)
// PresetBuilder 用于构建基于 nnet 协议的服务器预设。
type PresetBuilder struct {
baseConfig config.Config
configMutators []func(*Config)
setupSteps []func(Server) error
}
// NewPreset 创建一个带有推荐默认值的预设构建器。
// 默认启用 nnet 应用层协议与 Prometheus 指标导出路径。
func NewPreset() *PresetBuilder {
cfg := config.DefaultConfig()
cfg.ApplicationProtocol = "nnet"
if cfg.Metrics == nil {
cfg.Metrics = &config.MetricsConfig{}
}
cfg.Metrics.Enabled = true
if cfg.Metrics.Path == "" {
cfg.Metrics.Path = "/metrics"
}
return &PresetBuilder{
baseConfig: *cfg,
configMutators: make([]func(*Config), 0),
setupSteps: make([]func(Server) error, 0),
}
}
// Config 返回底层配置副本的引用,方便高级自定义。
// 对返回值的修改会影响后续 Build 调用,但不会影响已构建的服务器。
func (p *PresetBuilder) Config() *Config {
return &p.baseConfig
}
// WithAddress 设置服务器监听地址。
func (p *PresetBuilder) WithAddress(addr string) *PresetBuilder {
return p.WithConfig(func(cfg *Config) {
cfg.Addr = addr
})
}
// WithConfig 追加一个配置变更回调,在 Build 前依次执行。
func (p *PresetBuilder) WithConfig(mutator func(*Config)) *PresetBuilder {
if mutator == nil {
return p
}
p.configMutators = append(p.configMutators, mutator)
return p
}
// WithLogger 设置日志配置。
func (p *PresetBuilder) WithLogger(loggerCfg *LoggerConfig) *PresetBuilder {
return p.WithConfig(func(cfg *Config) {
cfg.Logger = loggerCfg
})
}
// WithMetricsHandler 将 Metrics HTTP 处理器挂载到指定 mux。
// path 为空时默认为 `/metrics`。
func (p *PresetBuilder) WithMetricsHandler(mux *http.ServeMux, path string) *PresetBuilder {
if mux == nil {
return p
}
if path == "" {
path = "/metrics"
}
p.setupSteps = append(p.setupSteps, func(s Server) error {
mux.Handle(path, s.MetricsHandler())
return nil
})
return p.WithConfig(func(cfg *Config) {
if cfg.Metrics == nil {
cfg.Metrics = &config.MetricsConfig{}
}
cfg.Metrics.Enabled = true
cfg.Metrics.Path = path
})
}
// WithHealthHandler 将健康检查 HTTP 处理器挂载到指定 mux。
// path 为空时默认为 `/healthz`。
func (p *PresetBuilder) WithHealthHandler(mux *http.ServeMux, path string) *PresetBuilder {
if mux == nil {
return p
}
if path == "" {
path = "/healthz"
}
p.setupSteps = append(p.setupSteps, func(s Server) error {
mux.Handle(path, s.HealthHandler())
return nil
})
return p
}
// WithRouteString 追加一个基于字符串匹配的路由。
func (p *PresetBuilder) WithRouteString(pattern string, handler Handler, opts ...routerpkg.RouteOption) *PresetBuilder {
p.setupSteps = append(p.setupSteps, func(s Server) error {
s.Router().RegisterString(pattern, handler, opts...)
return nil
})
return p
}
// WithRouter 允许对路由器进行任意自定义操作。
func (p *PresetBuilder) WithRouter(setup func(routerpkg.Router)) *PresetBuilder {
if setup == nil {
return p
}
p.setupSteps = append(p.setupSteps, func(s Server) error {
setup(s.Router())
return nil
})
return p
}
// WithServerSetup 追加一个在服务器创建后执行的自定义步骤。
func (p *PresetBuilder) WithServerSetup(setup func(Server) error) *PresetBuilder {
if setup == nil {
return p
}
p.setupSteps = append(p.setupSteps, setup)
return p
}
// Build 根据当前预设构建服务器实例。
func (p *PresetBuilder) Build() (Server, error) {
cfgCopy := p.baseConfig
for _, mutate := range p.configMutators {
mutate(&cfgCopy)
}
server, err := NewServer(&cfgCopy)
if err != nil {
return nil, err
}
for _, step := range p.setupSteps {
if step == nil {
continue
}
if err := step(server); err != nil {
return nil, err
}
}
return server, nil
}