| ... | ... |
@@ -10,7 +10,7 @@ import ( |
| 10 | 10 |
"fmt" |
| 11 | 11 |
"github.com/dotcloud/docker/auth" |
| 12 | 12 |
"github.com/dotcloud/docker/engine" |
| 13 |
- "github.com/dotcloud/docker/pkg/socketactivation" |
|
| 13 |
+ "github.com/dotcloud/docker/pkg/listenbuffer" |
|
| 14 | 14 |
"github.com/dotcloud/docker/pkg/systemd" |
| 15 | 15 |
"github.com/dotcloud/docker/utils" |
| 16 | 16 |
"github.com/gorilla/mux" |
| ... | ... |
@@ -1163,7 +1163,7 @@ func ListenAndServe(proto, addr string, eng *engine.Engine, logging, enableCors |
| 1163 | 1163 |
} |
| 1164 | 1164 |
} |
| 1165 | 1165 |
|
| 1166 |
- l, err := socketactivation.NewActivationListener(proto, addr, activationLock, 15*time.Minute) |
|
| 1166 |
+ l, err := listenbuffer.NewListenBuffer(proto, addr, activationLock, 15*time.Minute) |
|
| 1167 | 1167 |
if err != nil {
|
| 1168 | 1168 |
return err |
| 1169 | 1169 |
} |
| 1170 | 1170 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,61 @@ |
| 0 |
+/* |
|
| 1 |
+ Package to allow go applications to immediately start |
|
| 2 |
+ listening on a socket, unix, tcp, udp but hold connections |
|
| 3 |
+ until the application has booted and is ready to accept them |
|
| 4 |
+*/ |
|
| 5 |
+package listenbuffer |
|
| 6 |
+ |
|
| 7 |
+import ( |
|
| 8 |
+ "fmt" |
|
| 9 |
+ "net" |
|
| 10 |
+ "time" |
|
| 11 |
+) |
|
| 12 |
+ |
|
| 13 |
+// NewListenBuffer returns a listener listening on addr with the protocol. It sets the |
|
| 14 |
+// timeout to wait on first connection before an error is returned |
|
| 15 |
+func NewListenBuffer(proto, addr string, activate chan struct{}, timeout time.Duration) (net.Listener, error) {
|
|
| 16 |
+ wrapped, err := net.Listen(proto, addr) |
|
| 17 |
+ if err != nil {
|
|
| 18 |
+ return nil, err |
|
| 19 |
+ } |
|
| 20 |
+ |
|
| 21 |
+ return &defaultListener{
|
|
| 22 |
+ wrapped: wrapped, |
|
| 23 |
+ activate: activate, |
|
| 24 |
+ timeout: timeout, |
|
| 25 |
+ }, nil |
|
| 26 |
+} |
|
| 27 |
+ |
|
| 28 |
+type defaultListener struct {
|
|
| 29 |
+ wrapped net.Listener // the real listener to wrap |
|
| 30 |
+ ready bool // is the listner ready to start accpeting connections |
|
| 31 |
+ activate chan struct{}
|
|
| 32 |
+ timeout time.Duration // how long to wait before we consider this an error |
|
| 33 |
+} |
|
| 34 |
+ |
|
| 35 |
+func (l *defaultListener) Close() error {
|
|
| 36 |
+ return l.wrapped.Close() |
|
| 37 |
+} |
|
| 38 |
+ |
|
| 39 |
+func (l *defaultListener) Addr() net.Addr {
|
|
| 40 |
+ return l.wrapped.Addr() |
|
| 41 |
+} |
|
| 42 |
+ |
|
| 43 |
+func (l *defaultListener) Accept() (net.Conn, error) {
|
|
| 44 |
+ // if the listen has been told it is ready then we can go ahead and |
|
| 45 |
+ // start returning connections |
|
| 46 |
+ if l.ready {
|
|
| 47 |
+ return l.wrapped.Accept() |
|
| 48 |
+ } |
|
| 49 |
+ |
|
| 50 |
+ select {
|
|
| 51 |
+ case <-time.After(l.timeout): |
|
| 52 |
+ // close the connection so any clients are disconnected |
|
| 53 |
+ l.Close() |
|
| 54 |
+ return nil, fmt.Errorf("timeout (%s) reached waiting for listener to become ready", l.timeout.String())
|
|
| 55 |
+ case <-l.activate: |
|
| 56 |
+ l.ready = true |
|
| 57 |
+ return l.Accept() |
|
| 58 |
+ } |
|
| 59 |
+ panic("unreachable")
|
|
| 60 |
+} |
| 0 | 61 |
deleted file mode 100644 |
| ... | ... |
@@ -1,61 +0,0 @@ |
| 1 |
-/* |
|
| 2 |
- Package to allow go applications to immediately start |
|
| 3 |
- listening on a socket, unix, tcp, udp but hold connections |
|
| 4 |
- until the application has booted and is ready to accept them |
|
| 5 |
-*/ |
|
| 6 |
-package socketactivation |
|
| 7 |
- |
|
| 8 |
-import ( |
|
| 9 |
- "fmt" |
|
| 10 |
- "net" |
|
| 11 |
- "time" |
|
| 12 |
-) |
|
| 13 |
- |
|
| 14 |
-// NewActivationListener returns a listener listening on addr with the protocol. It sets the |
|
| 15 |
-// timeout to wait on first connection before an error is returned |
|
| 16 |
-func NewActivationListener(proto, addr string, activate chan struct{}, timeout time.Duration) (net.Listener, error) {
|
|
| 17 |
- wrapped, err := net.Listen(proto, addr) |
|
| 18 |
- if err != nil {
|
|
| 19 |
- return nil, err |
|
| 20 |
- } |
|
| 21 |
- |
|
| 22 |
- return &defaultListener{
|
|
| 23 |
- wrapped: wrapped, |
|
| 24 |
- activate: activate, |
|
| 25 |
- timeout: timeout, |
|
| 26 |
- }, nil |
|
| 27 |
-} |
|
| 28 |
- |
|
| 29 |
-type defaultListener struct {
|
|
| 30 |
- wrapped net.Listener // the real listener to wrap |
|
| 31 |
- ready bool // is the listner ready to start accpeting connections |
|
| 32 |
- activate chan struct{}
|
|
| 33 |
- timeout time.Duration // how long to wait before we consider this an error |
|
| 34 |
-} |
|
| 35 |
- |
|
| 36 |
-func (l *defaultListener) Close() error {
|
|
| 37 |
- return l.wrapped.Close() |
|
| 38 |
-} |
|
| 39 |
- |
|
| 40 |
-func (l *defaultListener) Addr() net.Addr {
|
|
| 41 |
- return l.wrapped.Addr() |
|
| 42 |
-} |
|
| 43 |
- |
|
| 44 |
-func (l *defaultListener) Accept() (net.Conn, error) {
|
|
| 45 |
- // if the listen has been told it is ready then we can go ahead and |
|
| 46 |
- // start returning connections |
|
| 47 |
- if l.ready {
|
|
| 48 |
- return l.wrapped.Accept() |
|
| 49 |
- } |
|
| 50 |
- |
|
| 51 |
- select {
|
|
| 52 |
- case <-time.After(l.timeout): |
|
| 53 |
- // close the connection so any clients are disconnected |
|
| 54 |
- l.Close() |
|
| 55 |
- return nil, fmt.Errorf("timeout (%s) reached waiting for listener to become ready", l.timeout.String())
|
|
| 56 |
- case <-l.activate: |
|
| 57 |
- l.ready = true |
|
| 58 |
- return l.Accept() |
|
| 59 |
- } |
|
| 60 |
- panic("unreachable")
|
|
| 61 |
-} |