diff --git a/pkg/consensus/consensus.go b/pkg/consensus/consensus.go index d9963d2c4..882f8568f 100644 --- a/pkg/consensus/consensus.go +++ b/pkg/consensus/consensus.go @@ -67,8 +67,11 @@ type Service interface { Name() string // Start initializes dBFT and starts event loop for consensus service. // It must be called only when the sufficient amount of peers are connected. + // The service only starts once, subsequent calls to Start are no-op. Start() - // Shutdown stops dBFT event loop. + // Shutdown stops dBFT event loop. It can only be called once, subsequent calls + // to Shutdown on the same instance are no-op. The instance that was stopped can + // not be started again by calling Start (use a new instance if needed). Shutdown() // OnPayload is a callback to notify the Service about a newly received payload. diff --git a/pkg/network/server.go b/pkg/network/server.go index 91e591f8d..f8292a24b 100644 --- a/pkg/network/server.go +++ b/pkg/network/server.go @@ -233,7 +233,8 @@ func (s *Server) ID() uint32 { return s.id } -// Start will start the server and its underlying transport. +// Start will start the server and its underlying transport. Calling it twice +// is an error. func (s *Server) Start(errChan chan error) { s.log.Info("node started", zap.Uint32("blockHeight", s.chain.BlockHeight()), @@ -251,7 +252,8 @@ func (s *Server) Start(errChan chan error) { s.run() } -// Shutdown disconnects all peers and stops listening. +// Shutdown disconnects all peers and stops listening. Calling it twice is an error, +// once stopped the same intance of the Server can't be started again by calling Start. func (s *Server) Shutdown() { s.log.Info("shutting down server", zap.Int("peers", s.PeerCount())) s.transport.Close() diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index b647660b3..8643945b4 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -215,6 +215,7 @@ func (s *Server) Name() string { // Start creates a new JSON-RPC server listening on the configured port. It creates // goroutines needed internally and it returns its errors via errChan passed to New(). +// The Server only starts once, subsequent calls to Start are no-op. func (s *Server) Start() { if !s.config.Enabled { s.log.Info("RPC server is not enabled") @@ -260,7 +261,10 @@ func (s *Server) Start() { }() } -// Shutdown stops the RPC server if it's running. +// Shutdown stops the RPC server if it's running. It can only be called once, +// subsequent calls to Shutdown on the same instance are no-op. The instance +// that was stopped can not be started again by calling Start (use a new +// instance if needed). func (s *Server) Shutdown() { if !s.started.CAS(true, false) { return diff --git a/pkg/services/helpers/rpcbroadcaster/broadcaster.go b/pkg/services/helpers/rpcbroadcaster/broadcaster.go index e030dcb22..7b6620b2a 100644 --- a/pkg/services/helpers/rpcbroadcaster/broadcaster.go +++ b/pkg/services/helpers/rpcbroadcaster/broadcaster.go @@ -73,7 +73,8 @@ func (r *RPCBroadcaster) SendParams(params request.RawParams) { } } -// Shutdown implements oracle.Broadcaster. +// Shutdown implements oracle.Broadcaster. The same instance can't be Run again +// after the shutdown. func (r *RPCBroadcaster) Shutdown() { close(r.close) <-r.finished diff --git a/pkg/services/notary/notary.go b/pkg/services/notary/notary.go index 44325f48c..b3141a2c8 100644 --- a/pkg/services/notary/notary.go +++ b/pkg/services/notary/notary.go @@ -164,6 +164,7 @@ func (n *Notary) Name() string { } // Start runs a Notary module in a separate goroutine. +// The Notary only starts once, subsequent calls to Start are no-op. func (n *Notary) Start() { if !n.started.CAS(false, true) { return @@ -211,7 +212,9 @@ drainLoop: close(n.done) } -// Shutdown stops the Notary module. +// Shutdown stops the Notary module. It can only be called once, subsequent calls +// to Shutdown on the same instance are no-op. The instance that was stopped can +// not be started again by calling Start (use a new instance if needed). func (n *Notary) Shutdown() { if !n.started.CAS(true, false) { return diff --git a/pkg/services/oracle/oracle.go b/pkg/services/oracle/oracle.go index fc63af081..a88077dee 100644 --- a/pkg/services/oracle/oracle.go +++ b/pkg/services/oracle/oracle.go @@ -181,7 +181,9 @@ func (o *Oracle) Name() string { return "oracle" } -// Shutdown shutdowns Oracle. +// Shutdown shutdowns Oracle. It can only be called once, subsequent calls +// to Shutdown on the same instance are no-op. The instance that was stopped can +// not be started again by calling Start (use a new instance if needed). func (o *Oracle) Shutdown() { o.respMtx.Lock() defer o.respMtx.Unlock() @@ -195,6 +197,7 @@ func (o *Oracle) Shutdown() { } // Start runs the oracle service in a separate goroutine. +// The Oracle only starts once, subsequent calls to Start are no-op. func (o *Oracle) Start() { o.respMtx.Lock() if o.running { diff --git a/pkg/services/stateroot/service.go b/pkg/services/stateroot/service.go index 789452daa..158377ae2 100644 --- a/pkg/services/stateroot/service.go +++ b/pkg/services/stateroot/service.go @@ -33,7 +33,12 @@ type ( OnPayload(p *payload.Extensible) error AddSignature(height uint32, validatorIndex int32, sig []byte) error GetConfig() config.StateRoot + // Start runs service instance in a separate goroutine. + // The service only starts once, subsequent calls to Start are no-op. Start() + // Shutdown stops the service. It can only be called once, subsequent calls + // to Shutdown on the same instance are no-op. The instance that was stopped can + // not be started again by calling Start (use a new instance if needed). Shutdown() } diff --git a/pkg/services/stateroot/validators.go b/pkg/services/stateroot/validators.go index 36f7faaf4..536440aaf 100644 --- a/pkg/services/stateroot/validators.go +++ b/pkg/services/stateroot/validators.go @@ -23,6 +23,7 @@ func (s *service) Name() string { } // Start runs service instance in a separate goroutine. +// The service only starts once, subsequent calls to Start are no-op. func (s *service) Start() { if !s.started.CAS(false, true) { return @@ -63,7 +64,9 @@ drainloop: close(s.done) } -// Shutdown stops the service. +// Shutdown stops the service. It can only be called once, subsequent calls +// to Shutdown on the same instance are no-op. The instance that was stopped can +// not be started again by calling Start (use a new instance if needed). func (s *service) Shutdown() { if !s.started.CAS(true, false) { return