github.com/damirazo/docker@v1.9.0/pkg/listenbuffer/buffer.go (about) 1 /* 2 Package listenbuffer uses the kernel's listening backlog functionality to queue 3 connections, allowing applications to start listening immediately and handle 4 connections later. This is signaled by closing the activation channel passed to 5 the constructor. 6 7 The maximum amount of queued connections depends on the configuration of your 8 kernel (typically called SOMAXXCON) and cannot be configured in Go with the 9 net package. See `src/net/sock_platform.go` in the Go tree or consult your 10 kernel's manual. 11 12 activator := make(chan struct{}) 13 buffer, err := NewListenBuffer("tcp", "localhost:4000", activator) 14 if err != nil { 15 panic(err) 16 } 17 18 // will block until activator has been closed or is sent an event 19 client, err := buffer.Accept() 20 21 Somewhere else in your application once it's been booted: 22 23 close(activator) 24 25 `buffer.Accept()` will return the first client in the kernel listening queue, or 26 continue to block until a client connects or an error occurs. 27 */ 28 package listenbuffer 29 30 import "net" 31 32 // NewListenBuffer returns a net.Listener listening on addr with the protocol 33 // passed. The channel passed is used to activate the listenbuffer when the 34 // caller is ready to accept connections. 35 func NewListenBuffer(proto, addr string, activate <-chan struct{}) (net.Listener, error) { 36 wrapped, err := net.Listen(proto, addr) 37 if err != nil { 38 return nil, err 39 } 40 41 return &defaultListener{ 42 wrapped: wrapped, 43 activate: activate, 44 }, nil 45 } 46 47 // defaultListener is the buffered wrapper around the net.Listener 48 type defaultListener struct { 49 wrapped net.Listener // The net.Listener wrapped by listenbuffer 50 ready bool // Whether the listenbuffer has been activated 51 activate <-chan struct{} // Channel to control activation of the listenbuffer 52 } 53 54 // Close closes the wrapped socket. 55 func (l *defaultListener) Close() error { 56 return l.wrapped.Close() 57 } 58 59 // Addr returns the listening address of the wrapped socket. 60 func (l *defaultListener) Addr() net.Addr { 61 return l.wrapped.Addr() 62 } 63 64 // Accept returns a client connection on the wrapped socket if the listen buffer 65 // has been activated. To active the listenbuffer the activation channel passed 66 // to NewListenBuffer must have been closed or sent an event. 67 func (l *defaultListener) Accept() (net.Conn, error) { 68 // if the listen has been told it is ready then we can go ahead and 69 // start returning connections 70 if l.ready { 71 return l.wrapped.Accept() 72 } 73 <-l.activate 74 l.ready = true 75 return l.Accept() 76 }