github.com/nsqio/nsq@v1.3.0/nsqlookupd/nsqlookupd.go (about) 1 package nsqlookupd 2 3 import ( 4 "fmt" 5 "log" 6 "net" 7 "os" 8 "sync" 9 10 "github.com/nsqio/nsq/internal/http_api" 11 "github.com/nsqio/nsq/internal/protocol" 12 "github.com/nsqio/nsq/internal/util" 13 "github.com/nsqio/nsq/internal/version" 14 ) 15 16 type NSQLookupd struct { 17 sync.RWMutex 18 opts *Options 19 tcpListener net.Listener 20 httpListener net.Listener 21 tcpServer *tcpServer 22 waitGroup util.WaitGroupWrapper 23 DB *RegistrationDB 24 } 25 26 func New(opts *Options) (*NSQLookupd, error) { 27 var err error 28 29 if opts.Logger == nil { 30 opts.Logger = log.New(os.Stderr, opts.LogPrefix, log.Ldate|log.Ltime|log.Lmicroseconds) 31 } 32 l := &NSQLookupd{ 33 opts: opts, 34 DB: NewRegistrationDB(), 35 } 36 37 l.logf(LOG_INFO, version.String("nsqlookupd")) 38 39 l.tcpServer = &tcpServer{nsqlookupd: l} 40 l.tcpListener, err = net.Listen("tcp", opts.TCPAddress) 41 if err != nil { 42 return nil, fmt.Errorf("listen (%s) failed - %s", opts.TCPAddress, err) 43 } 44 l.httpListener, err = net.Listen("tcp", opts.HTTPAddress) 45 if err != nil { 46 return nil, fmt.Errorf("listen (%s) failed - %s", opts.HTTPAddress, err) 47 } 48 49 return l, nil 50 } 51 52 // Main starts an instance of nsqlookupd and returns an 53 // error if there was a problem starting up. 54 func (l *NSQLookupd) Main() error { 55 exitCh := make(chan error) 56 var once sync.Once 57 exitFunc := func(err error) { 58 once.Do(func() { 59 if err != nil { 60 l.logf(LOG_FATAL, "%s", err) 61 } 62 exitCh <- err 63 }) 64 } 65 66 l.waitGroup.Wrap(func() { 67 exitFunc(protocol.TCPServer(l.tcpListener, l.tcpServer, l.logf)) 68 }) 69 httpServer := newHTTPServer(l) 70 l.waitGroup.Wrap(func() { 71 exitFunc(http_api.Serve(l.httpListener, httpServer, "HTTP", l.logf)) 72 }) 73 74 err := <-exitCh 75 return err 76 } 77 78 func (l *NSQLookupd) RealTCPAddr() *net.TCPAddr { 79 return l.tcpListener.Addr().(*net.TCPAddr) 80 } 81 82 func (l *NSQLookupd) RealHTTPAddr() *net.TCPAddr { 83 return l.httpListener.Addr().(*net.TCPAddr) 84 } 85 86 func (l *NSQLookupd) Exit() { 87 if l.tcpListener != nil { 88 l.tcpListener.Close() 89 } 90 91 if l.tcpServer != nil { 92 l.tcpServer.Close() 93 } 94 95 if l.httpListener != nil { 96 l.httpListener.Close() 97 } 98 l.waitGroup.Wait() 99 }