feat: add preferred debug port planning

This commit is contained in:
QiuSW
2026-07-27 09:29:10 +08:00
parent 3f382a431d
commit 79630e0d48
10 changed files with 518 additions and 74 deletions
+60 -5
View File
@@ -25,11 +25,12 @@ type Settings struct {
}
type Instance struct {
ID string `json:"id"`
Name string `json:"name"`
ProxyID string `json:"proxyId,omitempty"`
Launch domain.LaunchSpec `json:"launch"`
UpdatedAt time.Time `json:"updatedAt"`
ID string `json:"id"`
Name string `json:"name"`
ProxyID string `json:"proxyId,omitempty"`
PreferredRemoteDebugPort int `json:"preferredRemoteDebugPort,omitempty"`
Launch domain.LaunchSpec `json:"launch"`
UpdatedAt time.Time `json:"updatedAt"`
}
// ProxyProfile is deliberately limited to a display name and a validated,
@@ -88,6 +89,9 @@ func (s *Store) Load() (File, error) {
if result.Settings.RemoteDebugStartPort == 0 {
result.Settings.RemoteDebugStartPort = domain.DefaultRemoteDebugPort
}
if err := normalizeInstanceRemoteDebugPorts(&result); err != nil {
return File{}, err
}
if err := normalizeProxyConfig(&result); err != nil {
return File{}, err
}
@@ -107,12 +111,18 @@ func DefaultSettings() Settings {
func (s *Store) Save(value File) error {
value.Version = currentVersion
if value.Settings.RemoteDebugStartPort == 0 {
value.Settings.RemoteDebugStartPort = domain.DefaultRemoteDebugPort
}
if value.Instances == nil {
value.Instances = []Instance{}
}
if value.Proxies == nil {
value.Proxies = []ProxyProfile{}
}
if err := normalizeInstanceRemoteDebugPorts(&value); err != nil {
return err
}
if err := normalizeProxyConfig(&value); err != nil {
return err
}
@@ -150,6 +160,51 @@ func (s *Store) Save(value File) error {
return nil
}
func normalizeInstanceRemoteDebugPorts(value *File) error {
if value == nil {
return errors.New("config is required")
}
start := value.Settings.RemoteDebugStartPort
if !domain.ValidRemoteDebugPort(start) {
return fmt.Errorf("invalid remote debug start port %d", start)
}
used := make(map[int]struct{}, len(value.Instances))
for _, instance := range value.Instances {
port := instance.PreferredRemoteDebugPort
if port == 0 {
continue
}
if !domain.ValidRemoteDebugPort(port) {
return fmt.Errorf("invalid preferred remote debug port %d", port)
}
if _, exists := used[port]; exists {
return fmt.Errorf("duplicate preferred remote debug port %d", port)
}
used[port] = struct{}{}
}
for index := range value.Instances {
if value.Instances[index].PreferredRemoteDebugPort != 0 {
continue
}
port, err := nextPreferredRemoteDebugPort(start, used)
if err != nil {
return err
}
value.Instances[index].PreferredRemoteDebugPort = port
used[port] = struct{}{}
}
return nil
}
func nextPreferredRemoteDebugPort(start int, used map[int]struct{}) (int, error) {
for port := start; port <= domain.MaxRemoteDebugPort; port++ {
if _, exists := used[port]; !exists {
return port, nil
}
}
return 0, errors.New("no preferred remote debug port is available")
}
func normalizeProxyConfig(value *File) error {
if value == nil {
return errors.New("config is required")