diff --git a/server/server.go b/server/server.go index 5633b64..435c942 100644 --- a/server/server.go +++ b/server/server.go @@ -22,6 +22,7 @@ type Server struct { app *application.RicochetApplication config Config metricsPack metrics.Monitors + closed bool } // Run starts a server with the given privateKey @@ -29,6 +30,7 @@ type Server struct { // TODO: handle HUP/KILL signals to exit and close Tor gracefully // TODO: handle user input to exit func (s *Server) Run(acn connectivity.ACN, serverConfig Config) { + s.closed = false s.config = serverConfig cwtchserver := new(application.RicochetApplication) s.metricsPack.Start(cwtchserver, serverConfig.ConfigDir, s.config.ServerReporting.LogMetricsToFile) @@ -83,12 +85,16 @@ func (s *Server) Run(acn connectivity.ACN, serverConfig Config) { } else { s.app.Run(listenService) } + if s.closed { + return + } time.Sleep(5 * time.Second) } } // Shutdown kills the app closing all connections and freeing all goroutines func (s *Server) Shutdown() { + s.closed = true s.app.Shutdown() s.metricsPack.Stop() } diff --git a/testing/cwtch_peer_server_integration_test.go b/testing/cwtch_peer_server_integration_test.go index fd2f48d..b49b7a5 100644 --- a/testing/cwtch_peer_server_integration_test.go +++ b/testing/cwtch_peer_server_integration_test.go @@ -8,6 +8,7 @@ import ( cwtchserver "cwtch.im/cwtch/server" "fmt" "git.openprivacy.ca/openprivacy/libricochet-go/connectivity" + "git.openprivacy.ca/openprivacy/libricochet-go/log" "golang.org/x/net/proxy" "os" "runtime" @@ -100,6 +101,7 @@ func TestCwtchPeerIntegration(t *testing.T) { // Hide logging "noise" numGoRoutinesStart := runtime.NumGoroutine() + log.AddEverythingFromPattern("connectivity") acn, err := connectivity.StartTor(".", "") if err != nil { t.Fatalf("Could not start Tor: %v", err) @@ -395,17 +397,22 @@ func TestCwtchPeerIntegration(t *testing.T) { time.Sleep(time.Second * 3) numGoRoutinesPostCarol := runtime.NumGoroutine() + fmt.Println("Shutting down ACN...") + acn.Close() + time.Sleep(time.Second * 2) // Server ^^ has a 5 second loop attempting reconnect before exiting + numGoRoutinesPostACN := runtime.NumGoroutine() + // Printing out the current goroutines // Very useful if we are leaking any. pprof.Lookup("goroutine").WriteTo(os.Stdout, 1) fmt.Printf("numGoRoutinesStart: %v\nnumGoRoutinesPostServer: %v\nnumGoRoutinesPostPeerStart: %v\nnumGoRoutinesPostPeerAndServerConnect: %v\n"+ - "numGoRoutinesPostAlice: %v\nnumGoRotinesPostCarolConnect: %v\nnumGoRoutinesPostBob: %v\nnumGoRoutinesPostServerShutdown: %v\nnumGoRoutinesPostCarol: %v\n", + "numGoRoutinesPostAlice: %v\nnumGoRotinesPostCarolConnect: %v\nnumGoRoutinesPostBob: %v\nnumGoRoutinesPostServerShutdown: %v\nnumGoRoutinesPostCarol: %v\nnumGoRoutinesPostACN: %v\n", numGoRoutinesStart, numGoRoutinesPostServer, numGoRoutinesPostPeerStart, numGoRoutinesPostServerConnect, - numGoRoutinesPostAlice, numGoRotinesPostCarolConnect, numGoRoutinesPostBob, numGoRoutinesPostServerShutdown, numGoRoutinesPostCarol) + numGoRoutinesPostAlice, numGoRotinesPostCarolConnect, numGoRoutinesPostBob, numGoRoutinesPostServerShutdown, numGoRoutinesPostCarol, numGoRoutinesPostACN) - if numGoRoutinesStart != numGoRoutinesPostCarol { - t.Logf("Number of GoRoutines at start (%v) does not match number of goRoutines after cleanup of peers and servers (%v), clean up failed, leak detected!", numGoRoutinesStart, numGoRoutinesPostCarol) + if numGoRoutinesStart != numGoRoutinesPostACN { + t.Errorf("Number of GoRoutines at start (%v) does not match number of goRoutines after cleanup of peers and servers (%v), clean up failed, leak detected!", numGoRoutinesStart, numGoRoutinesPostACN) } }