Files
netrunner/orchestrator/ports.go
T
Zach Kelling 4e2a4e432e chore: remove local replace directives and update dependencies
- Update github.com/luxfi/keys v1.0.5 → v1.0.6
- Update github.com/luxfi/genesis v1.5.18 → v1.5.19
- Remove local replace directives for keys and genesis
- Use published package versions for reproducible builds
2026-01-03 07:05:17 -08:00

96 lines
1.8 KiB
Go

// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
// SPDX-License-Identifier: BSD-3-Clause
package orchestrator
import (
"fmt"
"net"
"sync"
)
// PortManager manages port allocation for engines
type PortManager struct {
mu sync.Mutex
allocated map[uint16]bool
httpBase uint16
p2pBase uint16
}
// NewPortManager creates a new port manager
func NewPortManager() *PortManager {
return &PortManager{
allocated: make(map[uint16]bool),
httpBase: 9630,
p2pBase: 9631,
}
}
// AllocateHTTP allocates an HTTP port
func (pm *PortManager) AllocateHTTP() uint16 {
pm.mu.Lock()
defer pm.mu.Unlock()
port := pm.httpBase
for pm.isInUse(port) || pm.allocated[port] {
port += 10 // Skip by 10 to avoid conflicts with P2P ports
}
pm.allocated[port] = true
return port
}
// AllocateP2P allocates a P2P port
func (pm *PortManager) AllocateP2P() uint16 {
pm.mu.Lock()
defer pm.mu.Unlock()
port := pm.p2pBase
for pm.isInUse(port) || pm.allocated[port] {
port += 10
}
pm.allocated[port] = true
return port
}
// Release releases a port
func (pm *PortManager) Release(port uint16) {
pm.mu.Lock()
defer pm.mu.Unlock()
delete(pm.allocated, port)
}
// isInUse checks if a port is in use
func (pm *PortManager) isInUse(port uint16) bool {
ln, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
if err != nil {
return true // Port is in use
}
ln.Close()
return false
}
// Reserve reserves specific ports
func (pm *PortManager) Reserve(ports ...uint16) error {
pm.mu.Lock()
defer pm.mu.Unlock()
// Check all ports are available first
for _, port := range ports {
if pm.allocated[port] {
return fmt.Errorf("port %d already allocated", port)
}
if pm.isInUse(port) {
return fmt.Errorf("port %d already in use", port)
}
}
// Reserve all ports
for _, port := range ports {
pm.allocated[port] = true
}
return nil
}