Merge pull request #32 from apcera/allow-external-listener

Allow nats to choose a random port when given port -1
This commit is contained in:
Alex Toombs
2014-06-09 10:11:31 -07:00
6 changed files with 80 additions and 2 deletions

View File

@@ -13,6 +13,11 @@ const (
// DEFAULT_PORT is the deault port for client connections.
DEFAULT_PORT = 4222
// RANDOM_PORT is the value for port that, when supplied, will cause the
// server to listen on a randomly-chosen available port. The resolved port
// is available via the Addr() method.
RANDOM_PORT = -1
// DEFAULT_HOST defaults to all interfaces.
DEFAULT_HOST = "0.0.0.0"

View File

@@ -213,6 +213,9 @@ func processOptions(opts *Options) {
}
if opts.Port == 0 {
opts.Port = DEFAULT_PORT
} else if opts.Port == RANDOM_PORT {
// Choose randomly inside of net.Listen
opts.Port = 0
}
if opts.MaxConn == 0 {
opts.MaxConn = DEFAULT_MAX_CONNECTIONS

View File

@@ -31,6 +31,16 @@ func TestDefaultOptions(t *testing.T) {
}
}
func TestOptions_RandomPort(t *testing.T) {
opts := &Options{Port: RANDOM_PORT}
processOptions(opts)
if opts.Port != 0 {
t.Fatalf("Process of options should have resolved random port to "+
"zero.\nexpected: %d\ngot: %d\n", 0, opts.Port)
}
}
func TestConfigFile(t *testing.T) {
golden := &Options{
Host: "apcera.me",

View File

@@ -274,6 +274,19 @@ func (s *Server) AcceptLoop() {
s.listener = l
s.mu.Unlock()
// Write resolved port back to options.
_, port, err := net.SplitHostPort(l.Addr().String())
if err != nil {
Fatalf("Error parsing server address (%s): %s", l.Addr().String(), e)
return
}
portNum, err := strconv.Atoi(port)
if err != nil {
Fatalf("Error parsing server address (%s): %s", l.Addr().String(), e)
return
}
s.opts.Port = portNum
tmpDelay := ACCEPT_MIN_SLEEP
for s.isRunning() {

41
test/port_test.go Normal file
View File

@@ -0,0 +1,41 @@
// Copyright 2014 Apcera Inc. All rights reserved.
package test
import (
"net"
"strconv"
"testing"
"github.com/apcera/gnatsd/server"
)
func TestResolveRandomPort(t *testing.T) {
opts := &server.Options{Port: server.RANDOM_PORT}
s := RunServer(opts)
defer s.Shutdown()
addr := s.Addr()
_, port, err := net.SplitHostPort(addr.String())
if err != nil {
t.Fatalf("Expected no error: Got %v\n", err)
}
portNum, err := strconv.Atoi(port)
if err != nil {
t.Fatalf("Expected no error: Got %v\n", err)
}
if portNum == server.DEFAULT_PORT {
t.Fatalf("Expected server to choose a random port\nGot: %d", server.DEFAULT_PORT)
}
if portNum == server.RANDOM_PORT {
t.Fatalf("Expected server to choose a random port\nGot: %d", server.RANDOM_PORT)
}
if opts.Port != portNum {
t.Fatalf("Options port (%d) should have been overridden by chosen random port (%d)",
opts.Port, portNum)
}
}

View File

@@ -56,10 +56,16 @@ func RunServer(opts *server.Options) *server.Server {
go s.Start()
// Make sure we are running and can bind before returning.
addr := fmt.Sprintf("%s:%d", opts.Host, opts.Port)
end := time.Now().Add(10 * time.Second)
for time.Now().Before(end) {
conn, err := net.Dial("tcp", addr)
addr := s.Addr()
if addr == nil {
time.Sleep(10 * time.Millisecond)
// Retry. We might take a little while to open a connection.
continue
}
conn, err := net.Dial("tcp", addr.String())
if err != nil {
time.Sleep(50 * time.Millisecond)
// Retry