diff --git a/blockchain/pool.go b/blockchain/pool.go index e15fd162a..518130338 100644 --- a/blockchain/pool.go +++ b/blockchain/pool.go @@ -68,12 +68,14 @@ func NewBlockPool(start int, requestsCh chan<- BlockRequest, timeoutsCh chan<- s return bp } -func (pool *BlockPool) AfterStart() { +func (pool *BlockPool) OnStart() { + pool.BaseService.OnStart() pool.repeater = NewRepeatTimer("", requestIntervalMS*time.Millisecond) go pool.run() } -func (pool *BlockPool) AfterStop() { +func (pool *BlockPool) OnStop() { + pool.BaseService.OnStop() pool.repeater.Stop() } diff --git a/blockchain/reactor.go b/blockchain/reactor.go index 7c3e42264..2c03fc1bd 100644 --- a/blockchain/reactor.go +++ b/blockchain/reactor.go @@ -76,14 +76,16 @@ func NewBlockchainReactor(state *sm.State, store *BlockStore, sync bool) *Blockc return bcR } -func (bcR *BlockchainReactor) AfterStart() { +func (bcR *BlockchainReactor) OnStart() { + bcR.BaseReactor.OnStart() if bcR.sync { bcR.pool.Start() go bcR.poolRoutine() } } -func (bcR *BlockchainReactor) AfterStop() { +func (bcR *BlockchainReactor) OnStop() { + bcR.BaseReactor.OnStop() bcR.pool.Stop() } diff --git a/common/service.go b/common/service.go index 97df343f7..c01391dda 100644 --- a/common/service.go +++ b/common/service.go @@ -2,7 +2,7 @@ Classical-inheritance-style service declarations. Services can be started, then stopped. -Users can override the AfterStart/AfterStop methods. +Users can override the OnStart/OnStop methods. These methods are guaranteed to be called at most once. Caller must ensure that Start() and Stop() are not called concurrently. It is ok to call Stop() without calling Start() first. @@ -19,16 +19,18 @@ func NewFooService() *FooService { fs := &FooService{ // init } - fs.BaseService = *BaseService(log, "FooService", fs) + fs.BaseService = *NewBaseService(log, "FooService", fs) return fs } -func (fs *FooService) AfterStart() { +func (fs *FooService) OnStart() { + fs.BaseService.OnStart() // Always call the overridden method. // initialize private fields // start subroutines, etc. } -func (fs *FooService) AfterStart() { +func (fs *FooService) OnStop() { + fs.BaseService.OnStop() // Always call the overridden method. // close/destroy private fields // stop subroutines, etc. } @@ -41,12 +43,10 @@ import "github.com/tendermint/tendermint/Godeps/_workspace/src/github.com/tender type Service interface { Start() bool - BeforeStart() - AfterStart() + OnStart() Stop() bool - BeforeStop() - AfterStop() + OnStop() IsRunning() bool @@ -80,8 +80,7 @@ func (bs *BaseService) Start() bool { } else { bs.log.Notice(Fmt("Starting %v", bs.name), "impl", bs.impl) } - bs.impl.BeforeStart() - bs.impl.AfterStart() + bs.impl.OnStart() return true } else { bs.log.Info(Fmt("Not starting %v -- already started", bs.name), "impl", bs.impl) @@ -90,17 +89,13 @@ func (bs *BaseService) Start() bool { } // Implements Service -func (bs *BaseService) BeforeStart() {} - -// Implements Service -func (bs *BaseService) AfterStart() {} +func (bs *BaseService) OnStart() {} // Implements Service func (bs *BaseService) Stop() bool { if atomic.CompareAndSwapUint32(&bs.stopped, 0, 1) { bs.log.Notice(Fmt("Stopping %v", bs.name), "impl", bs.impl) - bs.impl.BeforeStop() - bs.impl.AfterStop() + bs.impl.OnStop() return true } else { bs.log.Notice(Fmt("Not stopping %v", bs.name), "impl", bs.impl) @@ -109,10 +104,7 @@ func (bs *BaseService) Stop() bool { } // Implements Service -func (bs *BaseService) BeforeStop() {} - -// Implements Service -func (bs *BaseService) AfterStop() {} +func (bs *BaseService) OnStop() {} // Implements Service func (bs *BaseService) IsRunning() bool { @@ -138,17 +130,12 @@ func NewQuitService(log log15.Logger, name string, impl Service) *QuitService { } } -// Init .Quit in BeforeStart such that AfterStart of impls have access to Quit. -// NOTE: When overriding BeforeStart, call QuitService.BeforeStart() manually. -func (qs *QuitService) BeforeStart() { +// NOTE: when overriding OnStart, must call .QuitService.OnStart(). +func (qs *QuitService) OnStart() { qs.Quit = make(chan struct{}) } -// Close .Quit after Stop/BeforeStop/AfterStop -func (qs *QuitService) Stop() bool { - res := qs.BaseService.Stop() - if res { - close(qs.Quit) - } - return res +// NOTE: when overriding OnStop, must call .QuitService.OnStop(). +func (qs *QuitService) OnStop() { + close(qs.Quit) } diff --git a/consensus/reactor.go b/consensus/reactor.go index d63840fa8..1068edd45 100644 --- a/consensus/reactor.go +++ b/consensus/reactor.go @@ -49,15 +49,17 @@ func NewConsensusReactor(consensusState *ConsensusState, blockStore *bc.BlockSto return conR } -func (conR *ConsensusReactor) AfterStart() { +func (conR *ConsensusReactor) OnStart() { log.Notice("ConsensusReactor ", "fastSync", conR.fastSync) + conR.BaseReactor.OnStart() if !conR.fastSync { conR.conS.Start() } go conR.broadcastNewRoundStepRoutine() } -func (conR *ConsensusReactor) AfterStop() { +func (conR *ConsensusReactor) OnStop() { + conR.BaseReactor.OnStop() conR.conS.Stop() } diff --git a/consensus/state.go b/consensus/state.go index 12479a76e..0f24fe3e0 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -360,12 +360,14 @@ func (cs *ConsensusState) NewStepCh() chan *RoundState { return cs.newStepCh } -func (cs *ConsensusState) AfterStart() { +func (cs *ConsensusState) OnStart() { + cs.BaseService.OnStart() cs.scheduleRound0(cs.Height) } -func (cs *ConsensusState) AfterStop() { +func (cs *ConsensusState) OnStop() { // It's mostly asynchronous so, there's not much to stop. + cs.BaseService.OnStop() } // EnterNewRound(height, 0) at cs.StartTime. diff --git a/events/events.go b/events/events.go index 14ea8b180..4db658236 100644 --- a/events/events.go +++ b/events/events.go @@ -31,12 +31,14 @@ func NewEventSwitch() *EventSwitch { return evsw } -func (evsw *EventSwitch) AfterStart() { +func (evsw *EventSwitch) OnStart() { + evsw.BaseService.OnStart() evsw.eventCells = make(map[string]*eventCell) evsw.listeners = make(map[string]*eventListener) } -func (evsw *EventSwitch) AfterStop() { +func (evsw *EventSwitch) OnStop() { + evsw.BaseService.OnStop() evsw.eventCells = nil evsw.listeners = nil } diff --git a/mempool/reactor.go b/mempool/reactor.go index 0a9b97325..3e930985f 100644 --- a/mempool/reactor.go +++ b/mempool/reactor.go @@ -34,9 +34,9 @@ func NewMempoolReactor(mempool *Mempool) *MempoolReactor { return memR } -// func (memR *MempoolReactor) AfterStart() {} +// func (memR *MempoolReactor) OnStart() { memR.BaseReactor.OnStart() } -// func (memR *MempoolReactor) AfterStop() {} +// func (memR *MempoolReactor) OnStop() { memR.BaseReactor.OnStop() } // Implements Reactor func (memR *MempoolReactor) GetChannels() []*p2p.ChannelDescriptor { diff --git a/p2p/addrbook.go b/p2p/addrbook.go index a9e471339..bce9c9c43 100644 --- a/p2p/addrbook.go +++ b/p2p/addrbook.go @@ -121,13 +121,15 @@ func (a *AddrBook) init() { } } -func (a *AddrBook) AfterStart() { +func (a *AddrBook) OnStart() { + a.QuitService.OnStart() a.loadFromFile(a.filePath) a.wg.Add(1) go a.saveRoutine() } -func (a *AddrBook) AfterStop() { +func (a *AddrBook) OnStop() { + a.QuitService.OnStop() a.wg.Wait() } diff --git a/p2p/connection.go b/p2p/connection.go index 48940b24a..1c0bfd6d5 100644 --- a/p2p/connection.go +++ b/p2p/connection.go @@ -127,7 +127,8 @@ func NewMConnection(conn net.Conn, chDescs []*ChannelDescriptor, onReceive recei return mconn } -func (c *MConnection) AfterStart() { +func (c *MConnection) OnStart() { + c.BaseService.OnStart() c.quit = make(chan struct{}) c.flushTimer = NewThrottleTimer("flush", flushThrottleMS*time.Millisecond) c.pingTimer = NewRepeatTimer("ping", pingTimeoutSeconds*time.Second) @@ -136,7 +137,8 @@ func (c *MConnection) AfterStart() { go c.recvRoutine() } -func (c *MConnection) AfterStop() { +func (c *MConnection) OnStop() { + c.BaseService.OnStop() c.flushTimer.Stop() c.pingTimer.Stop() c.chStatsTimer.Stop() diff --git a/p2p/listener.go b/p2p/listener.go index 67f3dded2..5085f0913 100644 --- a/p2p/listener.go +++ b/p2p/listener.go @@ -97,11 +97,13 @@ SKIP_UPNP: return dl } -func (l *DefaultListener) AfterStart() { +func (l *DefaultListener) OnStart() { + l.BaseService.OnStart() go l.listenRoutine() } -func (l *DefaultListener) AfterStop() { +func (l *DefaultListener) OnStop() { + l.BaseService.OnStop() l.listener.Close() } diff --git a/p2p/peer.go b/p2p/peer.go index 0b8b5c94b..48ab7343e 100644 --- a/p2p/peer.go +++ b/p2p/peer.go @@ -72,11 +72,13 @@ func newPeer(conn net.Conn, peerNodeInfo *types.NodeInfo, outbound bool, reactor return p } -func (p *Peer) AfterStart() { +func (p *Peer) OnStart() { + p.BaseService.OnStart() p.mconn.Start() } -func (p *Peer) AfterStop() { +func (p *Peer) OnStop() { + p.BaseService.OnStop() p.mconn.Stop() } diff --git a/p2p/pex_reactor.go b/p2p/pex_reactor.go index 601e48f06..6e7ee5430 100644 --- a/p2p/pex_reactor.go +++ b/p2p/pex_reactor.go @@ -41,11 +41,13 @@ func NewPEXReactor(book *AddrBook) *PEXReactor { return pexR } -func (pexR *PEXReactor) AfterStart() { +func (pexR *PEXReactor) OnStart() { + pexR.BaseReactor.OnStart() go pexR.ensurePeersRoutine() } -func (pexR *PEXReactor) AfterStop() { +func (pexR *PEXReactor) OnStop() { + pexR.BaseReactor.OnStop() } // Implements Reactor diff --git a/p2p/switch.go b/p2p/switch.go index 0c04c7ac9..ca2f51a15 100644 --- a/p2p/switch.go +++ b/p2p/switch.go @@ -153,7 +153,8 @@ func (sw *Switch) SetNodePrivKey(nodePrivKey acm.PrivKeyEd25519) { } // Switch.Start() starts all the reactors, peers, and listeners. -func (sw *Switch) AfterStart() { +func (sw *Switch) OnStart() { + sw.BaseService.OnStart() // Start reactors for _, reactor := range sw.reactors { reactor.Start() @@ -168,7 +169,8 @@ func (sw *Switch) AfterStart() { } } -func (sw *Switch) AfterStop() { +func (sw *Switch) OnStop() { + sw.BaseService.OnStop() // Stop listeners for _, listener := range sw.listeners { listener.Stop() diff --git a/rpc/server/handlers.go b/rpc/server/handlers.go index 530dc19e4..f43bb1029 100644 --- a/rpc/server/handlers.go +++ b/rpc/server/handlers.go @@ -241,14 +241,16 @@ func NewWSConnection(wsConn *websocket.Conn) *WSConnection { return con } -func (con *WSConnection) AfterStart() { +func (con *WSConnection) OnStart() { + con.QuitService.OnStart() // read subscriptions/unsubscriptions to events go con.read() // write responses con.write() } -func (con *WSConnection) AfterStop() { +func (con *WSConnection) OnStop() { + con.QuitService.OnStop() con.evsw.RemoveListener(con.id) // the write loop closes the websocket connection // when it exits its loop, and the read loop