From fb217cf80e7eacc1878a40ca7df0c51b130ba791 Mon Sep 17 00:00:00 2001 From: yusing Date: Sat, 5 Apr 2025 14:04:11 +0800 Subject: [PATCH] feat(config): initialize agents in parallel, speed up config loading --- agent/pkg/agent/config.go | 4 ++++ internal/config/config.go | 35 +++++++++++++++++++++++++++------ internal/config/types/config.go | 2 ++ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/agent/pkg/agent/config.go b/agent/pkg/agent/config.go index a0bcbab..371c684 100644 --- a/agent/pkg/agent/config.go +++ b/agent/pkg/agent/config.go @@ -181,6 +181,10 @@ func (cfg *AgentConfig) DialContext(ctx context.Context) (net.Conn, error) { return gphttp.DefaultDialer.DialContext(ctx, "tcp", cfg.Addr) } +func (cfg *AgentConfig) IsInitialized() bool { + return cfg.name != "" +} + func (cfg *AgentConfig) Name() string { return cfg.name } diff --git a/internal/config/config.go b/internal/config/config.go index bfab72e..2dacc66 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -9,6 +9,7 @@ import ( "sync" "time" + "github.com/yusing/go-proxy/agent/pkg/agent" "github.com/yusing/go-proxy/internal/api" "github.com/yusing/go-proxy/internal/autocert" "github.com/yusing/go-proxy/internal/common" @@ -274,17 +275,42 @@ func (cfg *Config) errIfExists(p *proxy.Provider) gperr.Error { return nil } +func (cfg *Config) initAgents(agentCfgs []*agent.AgentConfig) gperr.Error { + var wg sync.WaitGroup + var errs gperr.Builder + + wg.Add(len(agentCfgs)) + for _, agentCfg := range agentCfgs { + go func(agentCfg *agent.AgentConfig) { + defer wg.Done() + if err := agentCfg.Init(cfg.task.Context()); err != nil { + errs.Add(err.Subject(agentCfg.String())) + } else { + addAgent(agentCfg) + } + }(agentCfg) + } + wg.Wait() + return errs.Error() +} + func (cfg *Config) loadRouteProviders(providers *config.Providers) gperr.Error { errs := gperr.NewBuilder("route provider errors") results := gperr.NewBuilder("loaded route providers") removeAllAgents() - routeProviders := make([]*proxy.Provider, 0, len(providers.Agents)+len(providers.Docker)+len(providers.Files)) + n := len(providers.Agents) + len(providers.Docker) + len(providers.Files) + if n == 0 { + return nil + } + + routeProviders := make([]*proxy.Provider, 0, n) + + errs.Add(cfg.initAgents(providers.Agents)) for _, agent := range providers.Agents { - if err := agent.Init(cfg.task.Context()); err != nil { - errs.Add(err.Subject(agent.String())) + if !agent.IsInitialized() { // failed to initialize continue } addAgent(agent) @@ -296,9 +322,6 @@ func (cfg *Config) loadRouteProviders(providers *config.Providers) gperr.Error { for name, dockerHost := range providers.Docker { routeProviders = append(routeProviders, proxy.NewDockerProvider(name, dockerHost)) } - if len(routeProviders) == 0 { - return nil - } // check if all providers are unique (should not happen but just in case) for _, p := range routeProviders { diff --git a/internal/config/types/config.go b/internal/config/types/config.go index bad04b2..863c3de 100644 --- a/internal/config/types/config.go +++ b/internal/config/types/config.go @@ -14,6 +14,7 @@ import ( "github.com/yusing/go-proxy/internal/gperr" "github.com/yusing/go-proxy/internal/net/gphttp/accesslog" "github.com/yusing/go-proxy/internal/notif" + proxmox "github.com/yusing/go-proxy/internal/proxmox/types" "github.com/yusing/go-proxy/internal/utils" ) @@ -29,6 +30,7 @@ type ( Providers struct { Files []string `json:"include" yaml:"include,omitempty" validate:"unique,dive,config_file_exists"` Docker map[string]string `json:"docker" yaml:"docker,omitempty" validate:"unique,dive,unix_addr|url"` + Proxmox map[string]proxmox.Config `json:"proxmox" yaml:"proxmox,omitempty"` Agents []*agent.AgentConfig `json:"agents" yaml:"agents,omitempty" validate:"unique=Addr"` Notification []notif.NotificationConfig `json:"notification" yaml:"notification,omitempty" validate:"unique=ProviderName"` }