Files
-Fonu/internal/frp/multi_manager.go
T

105 lines
2.5 KiB
Go
Raw Normal View History

2026-09-23 09:40:59 +08:00
package frp
import (
"context"
"fmt"
"path/filepath"
"strings"
)
func (s *Service) managerForServer(serverID int64) *Manager {
s.managersMu.Lock()
defer s.managersMu.Unlock()
if manager, ok := s.managers[serverID]; ok {
return manager
}
bin, err := s.manager.BinaryPath()
if err != nil {
bin = s.cfg.FrpcBin
}
manager := NewManager(
bin,
s.serverConfigPath(serverID),
s.serverLogPath(serverID),
s.logger,
)
s.managers[serverID] = manager
return manager
}
func (s *Service) serverConfigPath(serverID int64) string {
return filepath.Join(s.cfg.FrpDir(), fmt.Sprintf("frpc-server-%d.toml", serverID))
}
func (s *Service) serverLogPath(serverID int64) string {
return filepath.Join(s.cfg.FrpDir(), fmt.Sprintf("frpc-server-%d.log", serverID))
}
func (s *Service) managerSnapshot() map[int64]*Manager {
s.managersMu.RLock()
defer s.managersMu.RUnlock()
result := make(map[int64]*Manager, len(s.managers))
for id, manager := range s.managers {
result[id] = manager
}
return result
}
func (s *Service) setManagerBinary(path string) {
s.manager.SetBinary(path)
for _, manager := range s.managerSnapshot() {
manager.SetBinary(path)
}
}
func (s *Service) removeManager(serverID int64) {
s.managersMu.Lock()
delete(s.managers, serverID)
s.managersMu.Unlock()
}
func latestRuntimeStatus(statuses []RuntimeStatus) RuntimeStatus {
result := RuntimeStatus{Status: "stopped"}
for _, status := range statuses {
if status.Status == "running" {
result.Status = "running"
}
if status.Configured {
result.Configured = true
}
result.EnabledProxies += status.EnabledProxies
if result.PID == 0 && status.PID != 0 {
result.PID = status.PID
}
if status.LastStartedAt > result.LastStartedAt {
result.LastStartedAt = status.LastStartedAt
}
if status.LastReloadedAt > result.LastReloadedAt {
result.LastReloadedAt = status.LastReloadedAt
}
if result.LastError == "" && status.LastError != "" {
result.LastError = status.LastError
}
if status.Version != "" && result.Version == "" {
result.Version = status.Version
}
}
if len(statuses) == 0 {
result.Status = "unknown"
}
return result
}
func (s *Service) waitForManagers(ctx context.Context, action func(*Manager) error) error {
var messages []string
for id, manager := range s.managerSnapshot() {
if err := action(manager); err != nil {
messages = append(messages, fmt.Sprintf("服务端 %d:%v", id, err))
}
}
if len(messages) > 0 {
return fmt.Errorf("%s", strings.Join(messages, ";"))
}
return nil
}