Skip to content

Instantly share code, notes, and snippets.

@tkroll
Last active February 14, 2022 03:58
Show Gist options
  • Save tkroll/d34f5b170ea8ca58ba7c597a146a75f4 to your computer and use it in GitHub Desktop.
Save tkroll/d34f5b170ea8ca58ba7c597a146a75f4 to your computer and use it in GitHub Desktop.
Version of https://github.com/ava-labs/avalanche-network-runner/blob/main/local/utils.go using sequential ports starting at 9650.
package local
import (
"context"
"fmt"
"net"
"time"
)
var port uint16 = 9650 - 1
const (
netListenTimeout = 3 * time.Second
)
// getFreePort generates a random port number and then
// verifies it is free. If it is, returns that port, otherwise retries.
// Returns an error if no free port is found within [netListenTimeout].
// Note that it is possible for [getFreePort] to return the same port twice.
func getFreePort() (uint16, error) {
ctx, cancel := context.WithTimeout(context.Background(), netListenTimeout)
defer cancel()
for {
select {
case <-ctx.Done():
return 0, ctx.Err()
default:
// increment port
port += 1
// Verify it's free by binding to it
l, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
if err != nil {
// Couldn't bind to this port. Try another.
continue
}
// We could bind to [port] so must be free.
_ = l.Close()
return port, nil
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment