diff --git a/embed/doc.go b/embed/doc.go index 362fee9bc..c555aa58e 100644 --- a/embed/doc.go +++ b/embed/doc.go @@ -19,6 +19,7 @@ Launch an embedded etcd server using the configuration defaults: import ( "log" + "time" "github.com/coreos/etcd/embed" ) @@ -31,6 +32,13 @@ Launch an embedded etcd server using the configuration defaults: log.Fatal(err) } defer e.Close() + select { + case <-e.Server.ReadyNotify(): + log.Printf("Server is ready!") + case <-time.After(60 * time.Second): + e.Server.Stop() // trigger a shutdown + log.Printf("Server took too long to start!") + } log.Fatal(<-e.Err()) } */ diff --git a/embed/etcd.go b/embed/etcd.go index 38ff40887..8aeda04a1 100644 --- a/embed/etcd.go +++ b/embed/etcd.go @@ -59,6 +59,8 @@ type Etcd struct { } // StartEtcd launches the etcd server and HTTP handlers for client/server communication. +// The returned Etcd.Server is not guaranteed to have joined the cluster. Wait +// on the Etcd.Server.ReadyNotify() channel to know when it completes and is ready for use. func StartEtcd(inCfg *Config) (e *Etcd, err error) { if err = inCfg.Validate(); err != nil { return nil, err @@ -130,7 +132,6 @@ func StartEtcd(inCfg *Config) (e *Etcd, err error) { if err = e.serve(); err != nil { return } - <-e.Server.ReadyNotify() return } diff --git a/etcdmain/etcd.go b/etcdmain/etcd.go index 2444023a4..f30d8b59e 100644 --- a/etcdmain/etcd.go +++ b/etcdmain/etcd.go @@ -202,6 +202,7 @@ func startEtcd(cfg *embed.Config) (<-chan struct{}, <-chan error, error) { return nil, nil, err } osutil.RegisterInterruptHandler(e.Server.Stop) + <-e.Server.ReadyNotify() // wait for e.Server to join the cluster return e.Server.StopNotify(), e.Err(), nil } diff --git a/integration/embed_test.go b/integration/embed_test.go index 1a8075bc5..4b27973fc 100644 --- a/integration/embed_test.go +++ b/integration/embed_test.go @@ -65,6 +65,9 @@ func TestEmbedEtcd(t *testing.T) { for i, tt := range tests { tests[i].cfg.Dir = dir e, err := embed.StartEtcd(&tests[i].cfg) + if e != nil { + <-e.Server.ReadyNotify() // wait for e.Server to join the cluster + } if tt.werr != "" { if err == nil || !strings.Contains(err.Error(), tt.werr) { t.Errorf("%d: expected error with %q, got %v", i, tt.werr, err)