diff --git a/blockchain/pool.go b/blockchain/pool.go index e15fd162..51813033 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 7c3e4226..2c03fc1b 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 97df343f..c01391dd 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 d63840fa..1068edd4 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 12479a76..0f24fe3e 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 14ea8b18..4db65823 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 0a9b9732..3e930985 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 a9e47133..bce9c9c4 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 48940b24..1c0bfd6d 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 67f3dded..5085f091 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 0b8b5c94..48ab7343 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 601e48f0..6e7ee543 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 0c04c7ac..ca2f51a1 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 530dc19e..f43bb102 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