commit
f9e3db0373
|
@ -23,23 +23,23 @@ func (se StackError) Error() string {
|
||||||
// A panic resulting from a sanity check means there is a programmer error
|
// A panic resulting from a sanity check means there is a programmer error
|
||||||
// and some gaurantee is not satisfied.
|
// and some gaurantee is not satisfied.
|
||||||
func PanicSanity(v interface{}) {
|
func PanicSanity(v interface{}) {
|
||||||
panic(Fmt("Paniced on a Sanity Check: %v", v))
|
panic(Fmt("Panicked on a Sanity Check: %v", v))
|
||||||
}
|
}
|
||||||
|
|
||||||
// A panic here means something has gone horribly wrong, in the form of data corruption or
|
// A panic here means something has gone horribly wrong, in the form of data corruption or
|
||||||
// failure of the operating system. In a correct/healthy system, these should never fire.
|
// failure of the operating system. In a correct/healthy system, these should never fire.
|
||||||
// If they do, it's indicative of a much more serious problem.
|
// If they do, it's indicative of a much more serious problem.
|
||||||
func PanicCrisis(v interface{}) {
|
func PanicCrisis(v interface{}) {
|
||||||
panic(Fmt("Paniced on a Crisis: %v", v))
|
panic(Fmt("Panicked on a Crisis: %v", v))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indicates a failure of consensus. Someone was malicious or something has
|
// Indicates a failure of consensus. Someone was malicious or something has
|
||||||
// gone horribly wrong. These should really boot us into an "emergency-recover" mode
|
// gone horribly wrong. These should really boot us into an "emergency-recover" mode
|
||||||
func PanicConsensus(v interface{}) {
|
func PanicConsensus(v interface{}) {
|
||||||
panic(Fmt("Paniced on a Consensus Failure: %v", v))
|
panic(Fmt("Panicked on a Consensus Failure: %v", v))
|
||||||
}
|
}
|
||||||
|
|
||||||
// For those times when we're not sure if we should panic
|
// For those times when we're not sure if we should panic
|
||||||
func PanicQ(v interface{}) {
|
func PanicQ(v interface{}) {
|
||||||
panic(Fmt("Paniced questionably: %v", v))
|
panic(Fmt("Panicked questionably: %v", v))
|
||||||
}
|
}
|
||||||
|
|
87
service.go
87
service.go
|
@ -1,42 +1,3 @@
|
||||||
/*
|
|
||||||
|
|
||||||
Classical-inheritance-style service declarations.
|
|
||||||
Services can be started, then stopped, then optionally restarted.
|
|
||||||
Users can override the OnStart/OnStop methods.
|
|
||||||
By default, these methods are guaranteed to be called at most once.
|
|
||||||
A call to Reset will panic, unless OnReset is overwritten, allowing OnStart/OnStop to be called again.
|
|
||||||
Caller must ensure that Start() and Stop() are not called concurrently.
|
|
||||||
It is ok to call Stop() without calling Start() first.
|
|
||||||
Services cannot be re-started unless OnReset is overwritten to allow it.
|
|
||||||
|
|
||||||
Typical usage:
|
|
||||||
|
|
||||||
type FooService struct {
|
|
||||||
BaseService
|
|
||||||
// private fields
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFooService() *FooService {
|
|
||||||
fs := &FooService{
|
|
||||||
// init
|
|
||||||
}
|
|
||||||
fs.BaseService = *NewBaseService(log, "FooService", fs)
|
|
||||||
return fs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fs *FooService) OnStart() error {
|
|
||||||
fs.BaseService.OnStart() // Always call the overridden method.
|
|
||||||
// initialize private fields
|
|
||||||
// start subroutines, etc.
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fs *FooService) OnStop() error {
|
|
||||||
fs.BaseService.OnStop() // Always call the overridden method.
|
|
||||||
// close/destroy private fields
|
|
||||||
// stop subroutines, etc.
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -60,6 +21,48 @@ type Service interface {
|
||||||
String() string
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Classical-inheritance-style service declarations. Services can be started, then
|
||||||
|
stopped, then optionally restarted.
|
||||||
|
|
||||||
|
Users can override the OnStart/OnStop methods. In the absence of errors, these
|
||||||
|
methods are guaranteed to be called at most once. If OnStart returns an error,
|
||||||
|
service won't be marked as started, so the user can call Start again.
|
||||||
|
|
||||||
|
A call to Reset will panic, unless OnReset is overwritten, allowing
|
||||||
|
OnStart/OnStop to be called again.
|
||||||
|
|
||||||
|
The caller must ensure that Start and Stop are not called concurrently.
|
||||||
|
|
||||||
|
It is ok to call Stop without calling Start first.
|
||||||
|
|
||||||
|
Typical usage:
|
||||||
|
|
||||||
|
type FooService struct {
|
||||||
|
BaseService
|
||||||
|
// private fields
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFooService() *FooService {
|
||||||
|
fs := &FooService{
|
||||||
|
// init
|
||||||
|
}
|
||||||
|
fs.BaseService = *NewBaseService(log, "FooService", fs)
|
||||||
|
return fs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fs *FooService) OnStart() error {
|
||||||
|
fs.BaseService.OnStart() // Always call the overridden method.
|
||||||
|
// initialize private fields
|
||||||
|
// start subroutines, etc.
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fs *FooService) OnStop() error {
|
||||||
|
fs.BaseService.OnStop() // Always call the overridden method.
|
||||||
|
// close/destroy private fields
|
||||||
|
// stop subroutines, etc.
|
||||||
|
}
|
||||||
|
*/
|
||||||
type BaseService struct {
|
type BaseService struct {
|
||||||
log log15.Logger
|
log log15.Logger
|
||||||
name string
|
name string
|
||||||
|
@ -94,6 +97,11 @@ func (bs *BaseService) Start() (bool, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err := bs.impl.OnStart()
|
err := bs.impl.OnStart()
|
||||||
|
if err != nil {
|
||||||
|
// revert flag
|
||||||
|
atomic.StoreUint32(&bs.started, 0)
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
return true, err
|
return true, err
|
||||||
} else {
|
} else {
|
||||||
if bs.log != nil {
|
if bs.log != nil {
|
||||||
|
@ -136,6 +144,7 @@ func (bs *BaseService) Reset() (bool, 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{})
|
||||||
return true, bs.impl.OnReset()
|
return true, bs.impl.OnReset()
|
||||||
} else {
|
} else {
|
||||||
if bs.log != nil {
|
if bs.log != nil {
|
||||||
|
|
Loading…
Reference in New Issue