add Quit method to Service interface

remove deprecated QuitService
This commit is contained in:
Anton Kaliaev 2018-02-12 11:38:31 +04:00
parent 52ce4c20f8
commit a57340ffb5
No known key found for this signature in database
GPG Key ID: 7B6881D965918214
2 changed files with 30 additions and 26 deletions

View File

@ -5,6 +5,8 @@
BREAKING: BREAKING:
- [cli] WriteDemoConfig -> WriteConfigValues - [cli] WriteDemoConfig -> WriteConfigValues
- [common] added Quit method to Service interface, which returns a channel
which is closed once a service is stopped
## 0.6.1 (TBD) ## 0.6.1 (TBD)

View File

@ -35,9 +35,13 @@ type Service interface {
// Return true if the service is running // Return true if the service is running
IsRunning() bool IsRunning() bool
// Quit returns a channel, which is closed once service is stopped.
Quit() <-chan struct{}
// String representation of the service // String representation of the service
String() string String() string
// SetLogger sets a logger.
SetLogger(log.Logger) SetLogger(log.Logger)
} }
@ -88,12 +92,13 @@ type BaseService struct {
name string name string
started uint32 // atomic started uint32 // atomic
stopped uint32 // atomic stopped uint32 // atomic
Quit chan struct{} quit chan struct{}
// The "subclass" of BaseService // The "subclass" of BaseService
impl Service impl Service
} }
// NewBaseService creates a new BaseService.
func NewBaseService(logger log.Logger, name string, impl Service) *BaseService { func NewBaseService(logger log.Logger, name string, impl Service) *BaseService {
if logger == nil { if logger == nil {
logger = log.NewNopLogger() logger = log.NewNopLogger()
@ -102,16 +107,19 @@ func NewBaseService(logger log.Logger, name string, impl Service) *BaseService {
return &BaseService{ return &BaseService{
Logger: logger, Logger: logger,
name: name, name: name,
Quit: make(chan struct{}), quit: make(chan struct{}),
impl: impl, impl: impl,
} }
} }
// SetLogger implements Service by setting a logger.
func (bs *BaseService) SetLogger(l log.Logger) { func (bs *BaseService) SetLogger(l log.Logger) {
bs.Logger = l bs.Logger = l
} }
// Implements Servce // Start implements Service by calling OnStart (if defined). An error will be
// returned if the service is already running or stopped. Not to start the
// stopped service, you need to call Reset.
func (bs *BaseService) Start() error { 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 {
@ -133,17 +141,18 @@ func (bs *BaseService) Start() error {
} }
} }
// Implements Service // OnStart implements Service by doing nothing.
// NOTE: Do not put anything in here, // NOTE: Do not put anything in here,
// that way users don't need to call BaseService.OnStart() // that way users don't need to call BaseService.OnStart()
func (bs *BaseService) OnStart() error { return nil } func (bs *BaseService) OnStart() error { return nil }
// Implements Service // Stop implements Service by calling OnStop (if defined) and closing quit
// 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) {
bs.Logger.Info(Fmt("Stopping %v", bs.name), "impl", bs.impl) bs.Logger.Info(Fmt("Stopping %v", bs.name), "impl", bs.impl)
bs.impl.OnStop() bs.impl.OnStop()
close(bs.Quit) close(bs.quit)
return nil return nil
} else { } else {
bs.Logger.Debug(Fmt("Stopping %v (ignoring: already stopped)", bs.name), "impl", bs.impl) bs.Logger.Debug(Fmt("Stopping %v (ignoring: already stopped)", bs.name), "impl", bs.impl)
@ -151,12 +160,13 @@ func (bs *BaseService) Stop() error {
} }
} }
// Implements Service // OnStop implements Service by doing nothing.
// NOTE: Do not put anything in here, // NOTE: Do not put anything in here,
// that way users don't need to call BaseService.OnStop() // that way users don't need to call BaseService.OnStop()
func (bs *BaseService) OnStop() {} func (bs *BaseService) OnStop() {}
// Implements Service // Reset implements Service by calling OnReset callback (if defined). An error
// will be returned if the service is running.
func (bs *BaseService) Reset() error { func (bs *BaseService) Reset() error {
if !atomic.CompareAndSwapUint32(&bs.stopped, 1, 0) { if !atomic.CompareAndSwapUint32(&bs.stopped, 1, 0) {
bs.Logger.Debug(Fmt("Can't reset %v. Not stopped", bs.name), "impl", bs.impl) bs.Logger.Debug(Fmt("Can't reset %v. Not stopped", bs.name), "impl", bs.impl)
@ -166,41 +176,33 @@ func (bs *BaseService) Reset() error {
// whether or not we've started, we can reset // whether or not we've started, we can reset
atomic.CompareAndSwapUint32(&bs.started, 1, 0) atomic.CompareAndSwapUint32(&bs.started, 1, 0)
bs.Quit = make(chan struct{}) bs.quit = make(chan struct{})
return bs.impl.OnReset() return bs.impl.OnReset()
} }
// Implements Service // OnReset implements Service by panicking.
func (bs *BaseService) OnReset() error { func (bs *BaseService) OnReset() error {
PanicSanity("The service cannot be reset") PanicSanity("The service cannot be reset")
return nil return nil
} }
// Implements Service // IsRunning implements Service by returning true or false depending on the
// service's state.
func (bs *BaseService) IsRunning() bool { func (bs *BaseService) IsRunning() bool {
return atomic.LoadUint32(&bs.started) == 1 && atomic.LoadUint32(&bs.stopped) == 0 return atomic.LoadUint32(&bs.started) == 1 && atomic.LoadUint32(&bs.stopped) == 0
} }
// Wait blocks until the service is stopped.
func (bs *BaseService) Wait() { func (bs *BaseService) Wait() {
<-bs.Quit <-bs.quit
} }
// Implements Servce // String implements Servce by returning a string representation of the service.
func (bs *BaseService) String() string { func (bs *BaseService) String() string {
return bs.name return bs.name
} }
//---------------------------------------- // Quit Implements Service by returning a quit channel.
func (bs *BaseService) Quit() <-chan struct{} {
type QuitService struct { return bs.quit
BaseService
}
func NewQuitService(logger log.Logger, name string, impl Service) *QuitService {
if logger != nil {
logger.Info("QuitService is deprecated, use BaseService instead")
}
return &QuitService{
BaseService: *NewBaseService(logger, name, impl),
}
} }