Browse Source

Merge pull request #11 from tendermint/develop

Develop
pull/1842/head
Ethan Buchman 8 years ago
committed by GitHub
parent
commit
f9e3db0373
2 changed files with 52 additions and 43 deletions
  1. +4
    -4
      errors.go
  2. +48
    -39
      service.go

+ 4
- 4
errors.go View File

@ -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))
} }

+ 48
- 39
service.go View File

@ -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…
Cancel
Save