Browse Source

change service#Start to return just error (Refs #45)

```
@melekes
yeah, bool is superfluous
@ethanfrey
If I remember correctly when I was writing test code, if I call Start() on a Service that is already running, it returns (false, nil). Only if I try to legitimately start it, but it fails in startup do I get an error.
The distinction is quite important to make it safe for reentrant calls. The other approach would be to have a special error type like ErrAlreadyStarted, then check for that in your code explicitly. Kind of like if I make a db call in gorm, and get an error, I check if it is a RecordNotFound error, or whether there was a real error with the db query.
@melekes
Ah, I see. Thanks. I must say I like ErrAlreadyStarted approach more (not just in Golang)
```
pull/1842/head
Anton Kaliaev 7 years ago
parent
commit
4123d54bf6
No known key found for this signature in database GPG Key ID: 7B6881D965918214
2 changed files with 26 additions and 20 deletions
  1. +12
    -6
      common/service.go
  2. +14
    -14
      events/events_test.go

+ 12
- 6
common/service.go View File

@ -1,13 +1,19 @@
package common
import (
"errors"
"sync/atomic"
"github.com/tendermint/tmlibs/log"
)
var (
ErrAlreadyStarted = errors.New("already started")
ErrAlreadyStopped = errors.New("already stopped")
)
type Service interface {
Start() (bool, error)
Start() error
OnStart() error
Stop() bool
@ -94,11 +100,11 @@ func (bs *BaseService) SetLogger(l log.Logger) {
}
// Implements Servce
func (bs *BaseService) Start() (bool, error) {
func (bs *BaseService) Start() error {
if atomic.CompareAndSwapUint32(&bs.started, 0, 1) {
if atomic.LoadUint32(&bs.stopped) == 1 {
bs.Logger.Error(Fmt("Not starting %v -- already stopped", bs.name), "impl", bs.impl)
return false, nil
return ErrAlreadyStopped
} else {
bs.Logger.Info(Fmt("Starting %v", bs.name), "impl", bs.impl)
}
@ -106,12 +112,12 @@ func (bs *BaseService) Start() (bool, error) {
if err != nil {
// revert flag
atomic.StoreUint32(&bs.started, 0)
return false, err
return err
}
return true, err
return nil
} else {
bs.Logger.Debug(Fmt("Not starting %v -- already started", bs.name), "impl", bs.impl)
return false, nil
return ErrAlreadyStarted
}
}


+ 14
- 14
events/events_test.go View File

@ -13,8 +13,8 @@ import (
// listener to an event, and sends a string "data".
func TestAddListenerForEventFireOnce(t *testing.T) {
evsw := NewEventSwitch()
started, err := evsw.Start()
if !started || err != nil {
err := evsw.Start()
if err != nil {
t.Errorf("Failed to start EventSwitch, error: %v", err)
}
messages := make(chan EventData)
@ -33,8 +33,8 @@ func TestAddListenerForEventFireOnce(t *testing.T) {
// listener to an event, and sends a thousand integers.
func TestAddListenerForEventFireMany(t *testing.T) {
evsw := NewEventSwitch()
started, err := evsw.Start()
if !started || err != nil {
err := evsw.Start()
if err != nil {
t.Errorf("Failed to start EventSwitch, error: %v", err)
}
doneSum := make(chan uint64)
@ -62,8 +62,8 @@ func TestAddListenerForEventFireMany(t *testing.T) {
// of the three events.
func TestAddListenerForDifferentEvents(t *testing.T) {
evsw := NewEventSwitch()
started, err := evsw.Start()
if !started || err != nil {
err := evsw.Start()
if err != nil {
t.Errorf("Failed to start EventSwitch, error: %v", err)
}
doneSum := make(chan uint64)
@ -107,8 +107,8 @@ func TestAddListenerForDifferentEvents(t *testing.T) {
// for each of the three events.
func TestAddDifferentListenerForDifferentEvents(t *testing.T) {
evsw := NewEventSwitch()
started, err := evsw.Start()
if !started || err != nil {
err := evsw.Start()
if err != nil {
t.Errorf("Failed to start EventSwitch, error: %v", err)
}
doneSum1 := make(chan uint64)
@ -167,8 +167,8 @@ func TestAddDifferentListenerForDifferentEvents(t *testing.T) {
// the listener and fires a thousand integers for the second event.
func TestAddAndRemoveListener(t *testing.T) {
evsw := NewEventSwitch()
started, err := evsw.Start()
if !started || err != nil {
err := evsw.Start()
if err != nil {
t.Errorf("Failed to start EventSwitch, error: %v", err)
}
doneSum1 := make(chan uint64)
@ -212,8 +212,8 @@ func TestAddAndRemoveListener(t *testing.T) {
// TestRemoveListener does basic tests on adding and removing
func TestRemoveListener(t *testing.T) {
evsw := NewEventSwitch()
started, err := evsw.Start()
if !started || err != nil {
err := evsw.Start()
if err != nil {
t.Errorf("Failed to start EventSwitch, error: %v", err)
}
count := 10
@ -265,8 +265,8 @@ func TestRemoveListener(t *testing.T) {
// `go test -race`, to examine for possible race conditions.
func TestRemoveListenersAsync(t *testing.T) {
evsw := NewEventSwitch()
started, err := evsw.Start()
if !started || err != nil {
err := evsw.Start()
if err != nil {
t.Errorf("Failed to start EventSwitch, error: %v", err)
}
doneSum1 := make(chan uint64)


Loading…
Cancel
Save