From d7bd48f5d2f79ae96224cb0baad9d5a55f6cdcb4 Mon Sep 17 00:00:00 2001
From: Andre Hahn Pereira <andrehp@users.noreply.github.com>
Date: Mon, 26 Aug 2019 10:11:03 -0300
Subject: [PATCH] Fix possible server startup concurrency (#108)

The fix is done by initializing the service discovery
module as the last one, ensuring other modules have already
initialized correctly
---
 app.go                            | 16 ++++++++--------
 cluster/etcd_service_discovery.go |  4 +---
 2 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/app.go b/app.go
index 9c3ee4e2..03069c3d 100644
--- a/app.go
+++ b/app.go
@@ -370,18 +370,18 @@ func Start() {
 			app.serviceDiscovery.AddListener(app.rpcClient.(*cluster.GRPCClient))
 		}
 
-		err := RegisterModuleBefore(app.serviceDiscovery, "serviceDiscovery")
-		if err != nil {
-			logger.Log.Fatal("failed to register service discovery module: %s", err.Error())
-		}
-		err = RegisterModuleBefore(app.rpcServer, "rpcServer")
-		if err != nil {
+		if err := RegisterModuleBefore(app.rpcServer, "rpcServer"); err != nil {
 			logger.Log.Fatal("failed to register rpc server module: %s", err.Error())
 		}
-		err = RegisterModuleBefore(app.rpcClient, "rpcClient")
-		if err != nil {
+		if err := RegisterModuleBefore(app.rpcClient, "rpcClient"); err != nil {
 			logger.Log.Fatal("failed to register rpc client module: %s", err.Error())
 		}
+		// set the service discovery as the last module to be started to ensure
+		// all modules have been properly initialized before the server starts
+		// receiving requests from other pitaya servers
+		if err := RegisterModuleAfter(app.serviceDiscovery, "serviceDiscovery"); err != nil {
+			logger.Log.Fatal("failed to register service discovery module: %s", err.Error())
+		}
 
 		app.router.SetServiceDiscovery(app.serviceDiscovery)
 
diff --git a/cluster/etcd_service_discovery.go b/cluster/etcd_service_discovery.go
index 11258dbd..5935e925 100644
--- a/cluster/etcd_service_discovery.go
+++ b/cluster/etcd_service_discovery.go
@@ -209,7 +209,6 @@ func (sd *etcdServiceDiscovery) bootstrapServer(server *Server) error {
 	}
 
 	sd.SyncServers()
-
 	return nil
 }
 
@@ -346,8 +345,7 @@ func (sd *etcdServiceDiscovery) Init() error {
 	sd.cli.Watcher = namespace.NewWatcher(sd.cli.Watcher, sd.etcdPrefix)
 	sd.cli.Lease = namespace.NewLease(sd.cli.Lease, sd.etcdPrefix)
 
-	err = sd.bootstrap()
-	if err != nil {
+	if err = sd.bootstrap(); err != nil {
 		return err
 	}