Browse Source

Merge pull request #7848 from gyuho/close-grpcc

embed: fix blocking Close before gRPC server start
Gyu-Ho Lee 8 years ago
parent
commit
fdf445b5a0
2 changed files with 50 additions and 3 deletions
  1. 12 3
      embed/etcd.go
  2. 38 0
      embed/serve_test.go

+ 12 - 3
embed/etcd.go

@@ -70,13 +70,21 @@ func StartEtcd(inCfg *Config) (e *Etcd, err error) {
 	if err = inCfg.Validate(); err != nil {
 	if err = inCfg.Validate(); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
+	serving := false
 	e = &Etcd{cfg: *inCfg, stopc: make(chan struct{})}
 	e = &Etcd{cfg: *inCfg, stopc: make(chan struct{})}
 	cfg := &e.cfg
 	cfg := &e.cfg
 	defer func() {
 	defer func() {
-		if e != nil && err != nil {
-			e.Close()
-			e = nil
+		if e == nil || err == nil {
+			return
+		}
+		if !serving {
+			// errored before starting gRPC server for serveCtx.grpcServerC
+			for _, sctx := range e.sctxs {
+				close(sctx.grpcServerC)
+			}
 		}
 		}
+		e.Close()
+		e = nil
 	}()
 	}()
 
 
 	if e.Peers, err = startPeerListeners(cfg); err != nil {
 	if e.Peers, err = startPeerListeners(cfg); err != nil {
@@ -137,6 +145,7 @@ func StartEtcd(inCfg *Config) (e *Etcd, err error) {
 	if err = e.serve(); err != nil {
 	if err = e.serve(); err != nil {
 		return
 		return
 	}
 	}
+	serving = true
 	return
 	return
 }
 }
 
 

+ 38 - 0
embed/serve_test.go

@@ -0,0 +1,38 @@
+// Copyright 2017 The etcd Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package embed
+
+import (
+	"io/ioutil"
+	"os"
+	"testing"
+
+	"github.com/coreos/etcd/auth"
+)
+
+// TestStartEtcdWrongToken ensures that StartEtcd with wrong configs returns with error.
+func TestStartEtcdWrongToken(t *testing.T) {
+	tdir, err := ioutil.TempDir(os.TempDir(), "token-test")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tdir)
+	cfg := NewConfig()
+	cfg.Dir = tdir
+	cfg.AuthToken = "wrong-token"
+	if _, err = StartEtcd(cfg); err != auth.ErrInvalidAuthOpts {
+		t.Fatalf("expected %v, got %v", auth.ErrInvalidAuthOpts, err)
+	}
+}