mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-25 23:02:16 +00:00
64 lines
1.7 KiB
Go
64 lines
1.7 KiB
Go
|
package common
|
||
|
|
||
|
import "sync/atomic"
|
||
|
|
||
|
// BaseService represents a service that can be started then stopped,
|
||
|
// but cannot be restarted.
|
||
|
// .Start() calls the onStart callback function, and .Stop() calls onStop.
|
||
|
// It is meant to be embedded into service structs.
|
||
|
// The user must ensure that Start() and Stop() are not called concurrently.
|
||
|
// It is ok to call Stop() without calling Start() first -- the onStop
|
||
|
// callback will be called, and the service will never start.
|
||
|
type BaseService struct {
|
||
|
name string
|
||
|
service interface{} // for log statements.
|
||
|
started uint32 // atomic
|
||
|
stopped uint32 // atomic
|
||
|
onStart func()
|
||
|
onStop func()
|
||
|
}
|
||
|
|
||
|
func NewBaseService(name string, service interface{}, onStart, onStop func()) *BaseService {
|
||
|
return &BaseService{
|
||
|
name: name,
|
||
|
service: service,
|
||
|
onStart: onStart,
|
||
|
onStop: onStop,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (bs *BaseService) Start() bool {
|
||
|
if atomic.CompareAndSwapUint32(&bs.started, 0, 1) {
|
||
|
if atomic.LoadUint32(&bs.stopped) == 1 {
|
||
|
log.Warn(Fmt("Not starting %v -- already stopped", bs.name), "service", bs.service)
|
||
|
return false
|
||
|
} else {
|
||
|
log.Notice(Fmt("Starting %v", bs.name), "service", bs.service)
|
||
|
}
|
||
|
if bs.onStart != nil {
|
||
|
bs.onStart()
|
||
|
}
|
||
|
return true
|
||
|
} else {
|
||
|
log.Info(Fmt("Not starting %v -- already started", bs.name), "service", bs.service)
|
||
|
return false
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (bs *BaseService) Stop() bool {
|
||
|
if atomic.CompareAndSwapUint32(&bs.stopped, 0, 1) {
|
||
|
log.Notice(Fmt("Stopping %v", bs.name), "service", bs.service)
|
||
|
if bs.onStop != nil {
|
||
|
bs.onStop()
|
||
|
}
|
||
|
return true
|
||
|
} else {
|
||
|
log.Notice(Fmt("Not stopping %v", bs.name), "service", bs.service)
|
||
|
return false
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (bs *BaseService) IsRunning() bool {
|
||
|
return atomic.LoadUint32(&bs.started) == 1 && atomic.LoadUint32(&bs.stopped) == 0
|
||
|
}
|