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
+39 -2
View File
@@ -164,7 +164,7 @@ func runWindow(logger *slog.Logger) {
shell.SetProxies(proxyOptions(saved.Proxies))
rows := make([]ui.InstanceRow, 0, len(saved.Instances))
for _, item := range saved.Instances {
rows = append(rows, ui.InstanceRow{ID: item.ID, Name: item.Name, Browser: browserLabel(item.Launch.Kind), UserDataDir: item.Launch.UserDataDir, TargetURL: item.Launch.TargetURL, ProxyID: item.ProxyID, Status: "已退出"})
rows = append(rows, ui.InstanceRow{ID: item.ID, Name: item.Name, Browser: browserLabel(item.Launch.Kind), UserDataDir: item.Launch.UserDataDir, TargetURL: item.Launch.TargetURL, ProxyID: item.ProxyID, PreferredRemoteDebugPort: item.PreferredRemoteDebugPort, Status: "已退出"})
}
shell.SetInstances(rows)
shell.OnSave(func(value ui.SettingsState) {
@@ -493,7 +493,11 @@ func (s instanceStarter) Start(ctx context.Context, row ui.InstanceRow, settings
if err != nil {
return ui.InstanceStartOutcome{}, fmt.Errorf("无法找到%s可执行文件:%w", browserLabel(kind), err)
}
port, err := s.portAllocator.FindAvailableRemoteDebugPort(ctx, settings.RemoteDebugStartPort)
startPort := row.PreferredRemoteDebugPort
if !domain.ValidRemoteDebugPort(startPort) {
startPort = settings.RemoteDebugStartPort
}
port, err := findAvailableUnreservedRemoteDebugPort(ctx, s.portAllocator, startPort, settings.ReservedRemoteDebugPorts)
if err != nil {
return ui.InstanceStartOutcome{}, fmt.Errorf("无法分配本地调试端口:%w", err)
}
@@ -556,6 +560,7 @@ func mergeInstanceConfig(existing []config.Instance, rows []ui.InstanceRow) []co
item.Launch.UserDataDir = row.UserDataDir
item.Launch.TargetURL = row.TargetURL
item.ProxyID = row.ProxyID
item.PreferredRemoteDebugPort = row.PreferredRemoteDebugPort
if item.ProxyID != "" {
item.Launch.ProxyServer = ""
}
@@ -565,6 +570,38 @@ func mergeInstanceConfig(existing []config.Instance, rows []ui.InstanceRow) []co
return updated
}
func findAvailableUnreservedRemoteDebugPort(ctx context.Context, allocator browser.RemoteDebugPortAllocator, start int, reserved []int) (int, error) {
if allocator == nil {
return 0, errors.New("remote debug port allocator is required")
}
if !domain.ValidRemoteDebugPort(start) {
return 0, fmt.Errorf("invalid remote debug start port %d", start)
}
reservedSet := make(map[int]struct{}, len(reserved))
for _, port := range reserved {
if domain.ValidRemoteDebugPort(port) {
reservedSet[port] = struct{}{}
}
}
for candidate := start; candidate <= domain.MaxRemoteDebugPort; {
port, err := allocator.FindAvailableRemoteDebugPort(ctx, candidate)
if err != nil {
return 0, err
}
if !domain.ValidRemoteDebugPort(port) || port < candidate {
return 0, fmt.Errorf("port allocator returned invalid port %d", port)
}
if _, reservedByOtherInstance := reservedSet[port]; !reservedByOtherInstance {
return port, nil
}
if port == domain.MaxRemoteDebugPort {
break
}
candidate = port + 1
}
return 0, errors.New("no unreserved local remote debug port is available")
}
func mergeProxyConfig(existing []config.ProxyProfile, options []ui.ProxyOption) []config.ProxyProfile {
byID := make(map[string]config.ProxyProfile, len(existing))
for _, profile := range existing {