[common] revert started flag when service already stopped (#2326)

also, return ErrNotStarted when trying to stop a not-running service
This commit is contained in:
Anton Kaliaev 2018-09-13 03:07:29 +04:00 committed by Ethan Buchman
parent 1ea64fc27f
commit e3e3c13741
2 changed files with 15 additions and 3 deletions

View File

@ -9,8 +9,15 @@ import (
) )
var ( var (
// ErrAlreadyStarted is returned when somebody tries to start an already
// running service.
ErrAlreadyStarted = errors.New("already started") 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") 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. // 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.CompareAndSwapUint32(&bs.started, 0, 1) {
if atomic.LoadUint32(&bs.stopped) == 1 { if atomic.LoadUint32(&bs.stopped) == 1 {
bs.Logger.Error(fmt.Sprintf("Not starting %v -- already stopped", bs.name), "impl", bs.impl) bs.Logger.Error(fmt.Sprintf("Not starting %v -- already stopped", bs.name), "impl", bs.impl)
// revert flag
atomic.StoreUint32(&bs.started, 0)
return ErrAlreadyStopped return ErrAlreadyStopped
} }
bs.Logger.Info(fmt.Sprintf("Starting %v", bs.name), "impl", bs.impl) 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. // channel. An error will be returned if the service is already stopped.
func (bs *BaseService) Stop() error { func (bs *BaseService) Stop() error {
if atomic.CompareAndSwapUint32(&bs.stopped, 0, 1) { 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.Logger.Info(fmt.Sprintf("Stopping %v", bs.name), "impl", bs.impl)
bs.impl.OnStop() bs.impl.OnStop()
close(bs.quit) close(bs.quit)

View File

@ -174,9 +174,6 @@ func (c *WSClient) OnStart() error {
return nil return nil
} }
// OnStop implements cmn.Service.
func (c *WSClient) OnStop() {}
// Stop overrides cmn.Service#Stop. There is no other way to wait until Quit // Stop overrides cmn.Service#Stop. There is no other way to wait until Quit
// channel is closed. // channel is closed.
func (c *WSClient) Stop() error { func (c *WSClient) Stop() error {