Browse Source

etcdserver: stop server gracefully

Yicheng Qin 11 years ago
parent
commit
f7a0d5387b
2 changed files with 11 additions and 5 deletions
  1. 6 2
      etcdserver/server.go
  2. 5 3
      etcdserver/server_test.go

+ 6 - 2
etcdserver/server.go

@@ -127,6 +127,7 @@ type RaftTimer interface {
 type EtcdServer struct {
 type EtcdServer struct {
 	w          wait.Wait
 	w          wait.Wait
 	done       chan struct{}
 	done       chan struct{}
+	stopped    chan struct{}
 	id         uint64
 	id         uint64
 	attributes Attributes
 	attributes Attributes
 
 
@@ -247,6 +248,7 @@ func (s *EtcdServer) start() {
 	}
 	}
 	s.w = wait.New()
 	s.w = wait.New()
 	s.done = make(chan struct{})
 	s.done = make(chan struct{})
+	s.stopped = make(chan struct{})
 	s.stats.Initialize()
 	s.stats.Initialize()
 	// TODO: if this is an empty log, writes all peer infos
 	// TODO: if this is an empty log, writes all peer infos
 	// into the first entry
 	// into the first entry
@@ -312,16 +314,18 @@ func (s *EtcdServer) run() {
 		case <-syncC:
 		case <-syncC:
 			s.sync(defaultSyncTimeout)
 			s.sync(defaultSyncTimeout)
 		case <-s.done:
 		case <-s.done:
+			close(s.stopped)
 			return
 			return
 		}
 		}
 	}
 	}
 }
 }
 
 
-// Stop stops the server, and shuts down the running goroutine. Stop should be
-// called after a Start(s), otherwise it will block forever.
+// Stop stops the server gracefully, and shuts down the running goroutine.
+// Stop should be called after a Start(s), otherwise it will block forever.
 func (s *EtcdServer) Stop() {
 func (s *EtcdServer) Stop() {
 	s.node.Stop()
 	s.node.Stop()
 	close(s.done)
 	close(s.done)
+	<-s.stopped
 }
 }
 
 
 // Do interprets r and performs an operation on s.store according to r.Method
 // Do interprets r and performs an operation on s.store according to r.Method

+ 5 - 3
etcdserver/server_test.go

@@ -997,10 +997,12 @@ func TestPublish(t *testing.T) {
 // TestPublishStopped tests that publish will be stopped if server is stopped.
 // TestPublishStopped tests that publish will be stopped if server is stopped.
 func TestPublishStopped(t *testing.T) {
 func TestPublishStopped(t *testing.T) {
 	srv := &EtcdServer{
 	srv := &EtcdServer{
-		node: &nodeRecorder{},
-		w:    &waitRecorder{},
-		done: make(chan struct{}),
+		node:    &nodeRecorder{},
+		w:       &waitRecorder{},
+		done:    make(chan struct{}),
+		stopped: make(chan struct{}),
 	}
 	}
+	close(srv.stopped)
 	srv.Stop()
 	srv.Stop()
 	srv.publish(time.Hour)
 	srv.publish(time.Hour)
 }
 }