feat(config): initialize agents in parallel, speed up config loading

This commit is contained in:
yusing 2025-04-05 14:04:11 +08:00
parent 3689e72eff
commit fb217cf80e
3 changed files with 35 additions and 6 deletions

View file

@ -181,6 +181,10 @@ func (cfg *AgentConfig) DialContext(ctx context.Context) (net.Conn, error) {
return gphttp.DefaultDialer.DialContext(ctx, "tcp", cfg.Addr) return gphttp.DefaultDialer.DialContext(ctx, "tcp", cfg.Addr)
} }
func (cfg *AgentConfig) IsInitialized() bool {
return cfg.name != ""
}
func (cfg *AgentConfig) Name() string { func (cfg *AgentConfig) Name() string {
return cfg.name return cfg.name
} }

View file

@ -9,6 +9,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/yusing/go-proxy/agent/pkg/agent"
"github.com/yusing/go-proxy/internal/api" "github.com/yusing/go-proxy/internal/api"
"github.com/yusing/go-proxy/internal/autocert" "github.com/yusing/go-proxy/internal/autocert"
"github.com/yusing/go-proxy/internal/common" "github.com/yusing/go-proxy/internal/common"
@ -274,17 +275,42 @@ func (cfg *Config) errIfExists(p *proxy.Provider) gperr.Error {
return nil 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 { func (cfg *Config) loadRouteProviders(providers *config.Providers) gperr.Error {
errs := gperr.NewBuilder("route provider errors") errs := gperr.NewBuilder("route provider errors")
results := gperr.NewBuilder("loaded route providers") results := gperr.NewBuilder("loaded route providers")
removeAllAgents() 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 { for _, agent := range providers.Agents {
if err := agent.Init(cfg.task.Context()); err != nil { if !agent.IsInitialized() { // failed to initialize
errs.Add(err.Subject(agent.String()))
continue continue
} }
addAgent(agent) addAgent(agent)
@ -296,9 +322,6 @@ func (cfg *Config) loadRouteProviders(providers *config.Providers) gperr.Error {
for name, dockerHost := range providers.Docker { for name, dockerHost := range providers.Docker {
routeProviders = append(routeProviders, proxy.NewDockerProvider(name, dockerHost)) 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) // check if all providers are unique (should not happen but just in case)
for _, p := range routeProviders { for _, p := range routeProviders {

View file

@ -14,6 +14,7 @@ import (
"github.com/yusing/go-proxy/internal/gperr" "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/net/gphttp/accesslog" "github.com/yusing/go-proxy/internal/net/gphttp/accesslog"
"github.com/yusing/go-proxy/internal/notif" "github.com/yusing/go-proxy/internal/notif"
proxmox "github.com/yusing/go-proxy/internal/proxmox/types"
"github.com/yusing/go-proxy/internal/utils" "github.com/yusing/go-proxy/internal/utils"
) )
@ -29,6 +30,7 @@ type (
Providers struct { Providers struct {
Files []string `json:"include" yaml:"include,omitempty" validate:"unique,dive,config_file_exists"` 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"` 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"` Agents []*agent.AgentConfig `json:"agents" yaml:"agents,omitempty" validate:"unique=Addr"`
Notification []notif.NotificationConfig `json:"notification" yaml:"notification,omitempty" validate:"unique=ProviderName"` Notification []notif.NotificationConfig `json:"notification" yaml:"notification,omitempty" validate:"unique=ProviderName"`
} }