Files
sing-box-extended-mirror/adapter/service/manager.go
T

70 lines
1.6 KiB
Go

package service
import (
"context"
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/log"
E "github.com/sagernet/sing/common/exceptions"
)
var _ adapter.ServiceManager = (*Manager)(nil)
type Manager struct {
registry adapter.ServiceRegistry
access sync.Mutex
services []adapter.Service
serviceByTag map[string]adapter.Service
}
func NewManager(registry adapter.ServiceRegistry) *Manager {
return &Manager{
registry: registry,
serviceByTag: make(map[string]adapter.Service),
}
}
func (m *Manager) Start(stage adapter.StartStage, scope *adapter.Scope) error {
m.access.Lock()
services := m.services
m.access.Unlock()
for _, service := range services {
name := "service/" + service.Type() + "[" + service.Tag() + "]"
err := scope.Start(name, service, stage)
if err != nil {
return err
}
}
return nil
}
func (m *Manager) Services() []adapter.Service {
m.access.Lock()
defer m.access.Unlock()
return m.services
}
func (m *Manager) Get(tag string) (adapter.Service, bool) {
m.access.Lock()
service, found := m.serviceByTag[tag]
m.access.Unlock()
return service, found
}
func (m *Manager) Create(ctx context.Context, logger log.ContextLogger, tag string, serviceType string, options any) error {
service, err := m.registry.Create(ctx, logger, tag, serviceType, options)
if err != nil {
return err
}
m.access.Lock()
defer m.access.Unlock()
_, loaded := m.serviceByTag[tag]
if loaded {
return E.New("duplicate service tag: ", tag)
}
m.services = append(m.services, service)
m.serviceByTag[tag] = service
return nil
}