Skip to content

Commit 1588e80

Browse files
committed
do not start if port is busy
1 parent 81387b2 commit 1588e80

1 file changed

Lines changed: 68 additions & 0 deletions

File tree

main.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"embed"
55
"flag"
66
"fmt"
7+
"net"
78
"os"
89
"time"
910

@@ -29,6 +30,67 @@ var fclCdc []byte
2930
//go:embed cadence/*
3031
var _ embed.FS
3132

33+
// isPortAvailable checks if a port is available for binding
34+
func isPortAvailable(port int) bool {
35+
addr := fmt.Sprintf(":%d", port)
36+
listener, err := net.Listen("tcp", addr)
37+
if err != nil {
38+
return false
39+
}
40+
listener.Close()
41+
return true
42+
}
43+
44+
// checkRequiredPorts validates that all required ports are available
45+
func checkRequiredPorts(cfg *config.Config) error {
46+
if cfg.Network != "emulator" {
47+
// Only check ports in emulator mode
48+
return nil
49+
}
50+
51+
type portCheck struct {
52+
port int
53+
name string
54+
}
55+
56+
portsToCheck := []portCheck{
57+
{cfg.Ports.Emulator.GRPC, "Emulator gRPC"},
58+
{cfg.Ports.Emulator.REST, "Emulator REST"},
59+
{cfg.Ports.Emulator.Admin, "Emulator Admin"},
60+
{cfg.Ports.Emulator.Debugger, "Emulator Debugger"},
61+
{cfg.Ports.DevWallet, "Dev Wallet"},
62+
{cfg.Ports.EVM.RPC, "EVM Gateway RPC"},
63+
{cfg.Ports.EVM.Profiler, "EVM Gateway Profiler"},
64+
{cfg.Ports.EVM.Metrics, "EVM Gateway Metrics"},
65+
}
66+
67+
var unavailablePorts []string
68+
for _, pc := range portsToCheck {
69+
if !isPortAvailable(pc.port) {
70+
unavailablePorts = append(unavailablePorts, fmt.Sprintf("%s (port %d)", pc.name, pc.port))
71+
}
72+
}
73+
74+
if len(unavailablePorts) > 0 {
75+
return fmt.Errorf("the following ports are already in use:\n - %s\n\nPlease stop the services using these ports or configure different ports in your config file",
76+
joins(unavailablePorts, "\n - "))
77+
}
78+
79+
return nil
80+
}
81+
82+
// joins is a simple helper to join strings with a separator
83+
func joins(strs []string, sep string) string {
84+
if len(strs) == 0 {
85+
return ""
86+
}
87+
result := strs[0]
88+
for i := 1; i < len(strs); i++ {
89+
result += sep + strs[i]
90+
}
91+
return result
92+
}
93+
3294
func main() {
3395
// Parse command line flags
3496
configPath := flag.String("config", "", "Path to configuration file")
@@ -112,6 +174,12 @@ func main() {
112174
aetherLogger.Info().Msg("Using default configuration")
113175
}
114176

177+
// Check if required ports are available before starting services
178+
if err := checkRequiredPorts(cfg); err != nil {
179+
fmt.Printf("\nError: %v\n\n", err)
180+
os.Exit(1)
181+
}
182+
115183
// Initialize components based on whether we're following a network or running locally
116184
var emu *server.EmulatorServer
117185
var dw *devWallet.Server

0 commit comments

Comments
 (0)