From e3e3c13741acd4dbedb2d03e3f5cff42891cfaa4 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Thu, 13 Sep 2018 03:07:29 +0400 Subject: [PATCH] [common] revert started flag when service already stopped (#2326) also, return ErrNotStarted when trying to stop a not-running service --- libs/common/service.go | 15 +++++++++++++++ rpc/lib/client/ws_client.go | 3 --- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/libs/common/service.go b/libs/common/service.go index 03e392855..96a5e632a 100644 --- a/libs/common/service.go +++ b/libs/common/service.go @@ -9,8 +9,15 @@ import ( ) var ( + // ErrAlreadyStarted is returned when somebody tries to start an already + // running service. ErrAlreadyStarted = errors.New("already started") + // ErrAlreadyStopped is returned when somebody tries to stop an already + // stopped service (without resetting it). ErrAlreadyStopped = errors.New("already stopped") + // ErrNotStarted is returned when somebody tries to stop a not running + // service. + ErrNotStarted = errors.New("not started") ) // Service defines a service that can be started, stopped, and reset. @@ -124,6 +131,8 @@ func (bs *BaseService) Start() error { if atomic.CompareAndSwapUint32(&bs.started, 0, 1) { if atomic.LoadUint32(&bs.stopped) == 1 { bs.Logger.Error(fmt.Sprintf("Not starting %v -- already stopped", bs.name), "impl", bs.impl) + // revert flag + atomic.StoreUint32(&bs.started, 0) return ErrAlreadyStopped } bs.Logger.Info(fmt.Sprintf("Starting %v", bs.name), "impl", bs.impl) @@ -148,6 +157,12 @@ func (bs *BaseService) OnStart() error { return nil } // channel. An error will be returned if the service is already stopped. func (bs *BaseService) Stop() error { if atomic.CompareAndSwapUint32(&bs.stopped, 0, 1) { + if atomic.LoadUint32(&bs.started) == 0 { + bs.Logger.Error(fmt.Sprintf("Not stopping %v -- have not been started yet", bs.name), "impl", bs.impl) + // revert flag + atomic.StoreUint32(&bs.stopped, 0) + return ErrNotStarted + } bs.Logger.Info(fmt.Sprintf("Stopping %v", bs.name), "impl", bs.impl) bs.impl.OnStop() close(bs.quit) diff --git a/rpc/lib/client/ws_client.go b/rpc/lib/client/ws_client.go index cff285222..6da996e2c 100644 --- a/rpc/lib/client/ws_client.go +++ b/rpc/lib/client/ws_client.go @@ -174,9 +174,6 @@ func (c *WSClient) OnStart() error { return nil } -// OnStop implements cmn.Service. -func (c *WSClient) OnStop() {} - // Stop overrides cmn.Service#Stop. There is no other way to wait until Quit // channel is closed. func (c *WSClient) Stop() error {