mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-26 19:21:44 +00:00
Fix switch tests
This commit is contained in:
@ -94,13 +94,13 @@ func (n *Node) Start() {
|
|||||||
go n.inboundConnectionRoutine(l)
|
go n.inboundConnectionRoutine(l)
|
||||||
}
|
}
|
||||||
n.book.Start()
|
n.book.Start()
|
||||||
n.sw.StartAll()
|
n.sw.StartReactors()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) Stop() {
|
func (n *Node) Stop() {
|
||||||
log.Info("Stopping Node")
|
log.Info("Stopping Node")
|
||||||
// TODO: gracefully disconnect from peers.
|
// TODO: gracefully disconnect from peers.
|
||||||
n.sw.StopAll()
|
n.sw.Stop()
|
||||||
n.book.Stop()
|
n.book.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ func (pexR *PEXReactor) GetChannels() []*ChannelDescriptor {
|
|||||||
&ChannelDescriptor{
|
&ChannelDescriptor{
|
||||||
Id: PexChannel,
|
Id: PexChannel,
|
||||||
Priority: 1,
|
Priority: 1,
|
||||||
|
SendQueueCapacity: 10,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
. "github.com/tendermint/tendermint/common"
|
. "github.com/tendermint/tendermint/common"
|
||||||
@ -36,12 +35,10 @@ type Switch struct {
|
|||||||
peers *PeerSet
|
peers *PeerSet
|
||||||
dialing *CMap
|
dialing *CMap
|
||||||
listeners *CMap // listenerName -> chan interface{}
|
listeners *CMap // listenerName -> chan interface{}
|
||||||
running uint32 // atomic
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrSwitchDuplicatePeer = errors.New("Duplicate peer")
|
ErrSwitchDuplicatePeer = errors.New("Duplicate peer")
|
||||||
ErrSwitchStopped = errors.New("Switch stopped")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -58,17 +55,18 @@ func NewSwitch() *Switch {
|
|||||||
peers: NewPeerSet(),
|
peers: NewPeerSet(),
|
||||||
dialing: NewCMap(),
|
dialing: NewCMap(),
|
||||||
listeners: NewCMap(),
|
listeners: NewCMap(),
|
||||||
running: 0,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sw
|
return sw
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Not goroutine safe.
|
||||||
func (sw *Switch) SetChainId(hash []byte, network string) {
|
func (sw *Switch) SetChainId(hash []byte, network string) {
|
||||||
sw.chainId = hex.EncodeToString(hash) + "-" + network
|
sw.chainId = hex.EncodeToString(hash) + "-" + network
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sw *Switch) AddReactor(name string, reactor Reactor) {
|
// Not goroutine safe.
|
||||||
|
func (sw *Switch) AddReactor(name string, reactor Reactor) Reactor {
|
||||||
// Validate the reactor.
|
// Validate the reactor.
|
||||||
// No two reactors can share the same channel.
|
// No two reactors can share the same channel.
|
||||||
reactorChannels := reactor.GetChannels()
|
reactorChannels := reactor.GetChannels()
|
||||||
@ -81,51 +79,49 @@ func (sw *Switch) AddReactor(name string, reactor Reactor) {
|
|||||||
sw.reactorsByCh[chId] = reactor
|
sw.reactorsByCh[chId] = reactor
|
||||||
}
|
}
|
||||||
sw.reactors[name] = reactor
|
sw.reactors[name] = reactor
|
||||||
time.Sleep(1 * time.Second)
|
return reactor
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sw *Switch) StartReactor(name string) {
|
func (sw *Switch) Reactor(name string) Reactor {
|
||||||
atomic.StoreUint32(&sw.running, 1)
|
return sw.reactors[name]
|
||||||
sw.reactors[name].Start(sw)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convenience function
|
// Convenience function
|
||||||
func (sw *Switch) StartAll() {
|
func (sw *Switch) StartReactors() {
|
||||||
atomic.StoreUint32(&sw.running, 1)
|
|
||||||
for _, reactor := range sw.reactors {
|
for _, reactor := range sw.reactors {
|
||||||
reactor.Start(sw)
|
reactor.Start(sw)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sw *Switch) StopReactor(name string) {
|
|
||||||
sw.reactors[name].Stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convenience function
|
// Convenience function
|
||||||
// Not goroutine safe
|
func (sw *Switch) StopReactors() {
|
||||||
func (sw *Switch) StopAll() {
|
|
||||||
atomic.StoreUint32(&sw.running, 0)
|
|
||||||
// Stop each peer.
|
|
||||||
for _, peer := range sw.peers.List() {
|
|
||||||
peer.stop()
|
|
||||||
}
|
|
||||||
sw.peers = NewPeerSet()
|
|
||||||
// Stop all reactors.
|
// Stop all reactors.
|
||||||
for _, reactor := range sw.reactors {
|
for _, reactor := range sw.reactors {
|
||||||
reactor.Stop()
|
reactor.Stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not goroutine safe
|
// Convenience function
|
||||||
|
func (sw *Switch) StopPeers() {
|
||||||
|
// Stop each peer.
|
||||||
|
for _, peer := range sw.peers.List() {
|
||||||
|
peer.stop()
|
||||||
|
}
|
||||||
|
sw.peers = NewPeerSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convenience function
|
||||||
|
func (sw *Switch) Stop() {
|
||||||
|
sw.StopPeers()
|
||||||
|
sw.StopReactors()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not goroutine safe to modify.
|
||||||
func (sw *Switch) Reactors() map[string]Reactor {
|
func (sw *Switch) Reactors() map[string]Reactor {
|
||||||
return sw.reactors
|
return sw.reactors
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sw *Switch) AddPeerWithConnection(conn net.Conn, outbound bool) (*Peer, error) {
|
func (sw *Switch) AddPeerWithConnection(conn net.Conn, outbound bool) (*Peer, error) {
|
||||||
if atomic.LoadUint32(&sw.running) == 0 {
|
|
||||||
return nil, ErrSwitchStopped
|
|
||||||
}
|
|
||||||
|
|
||||||
peer := newPeer(conn, outbound, sw.reactorsByCh, sw.chDescs, sw.StopPeerForError)
|
peer := newPeer(conn, outbound, sw.reactorsByCh, sw.chDescs, sw.StopPeerForError)
|
||||||
|
|
||||||
// Add the peer to .peers
|
// Add the peer to .peers
|
||||||
@ -150,10 +146,6 @@ func (sw *Switch) AddPeerWithConnection(conn net.Conn, outbound bool) (*Peer, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sw *Switch) DialPeerWithAddress(addr *NetAddress) (*Peer, error) {
|
func (sw *Switch) DialPeerWithAddress(addr *NetAddress) (*Peer, error) {
|
||||||
if atomic.LoadUint32(&sw.running) == 0 {
|
|
||||||
return nil, ErrSwitchStopped
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debug("Dialing address", "address", addr)
|
log.Debug("Dialing address", "address", addr)
|
||||||
sw.dialing.Set(addr.String(), addr)
|
sw.dialing.Set(addr.String(), addr)
|
||||||
conn, err := addr.DialTimeout(peerDialTimeoutSeconds * time.Second)
|
conn, err := addr.DialTimeout(peerDialTimeoutSeconds * time.Second)
|
||||||
@ -179,9 +171,6 @@ func (sw *Switch) IsDialing(addr *NetAddress) bool {
|
|||||||
// trying to send for defaultSendTimeoutSeconds. Returns a channel
|
// trying to send for defaultSendTimeoutSeconds. Returns a channel
|
||||||
// which receives success values for each attempted send (false if times out)
|
// which receives success values for each attempted send (false if times out)
|
||||||
func (sw *Switch) Broadcast(chId byte, msg interface{}) chan bool {
|
func (sw *Switch) Broadcast(chId byte, msg interface{}) chan bool {
|
||||||
if atomic.LoadUint32(&sw.running) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
successChan := make(chan bool, len(sw.peers.List()))
|
successChan := make(chan bool, len(sw.peers.List()))
|
||||||
log.Debug("Broadcast", "channel", chId, "msg", msg)
|
log.Debug("Broadcast", "channel", chId, "msg", msg)
|
||||||
for _, peer := range sw.peers.List() {
|
for _, peer := range sw.peers.List() {
|
||||||
@ -239,7 +228,7 @@ func (sw *Switch) IsListening() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sw *Switch) doAddPeer(peer *Peer) {
|
func (sw *Switch) doAddPeer(peer *Peer) {
|
||||||
for name, reactor := range sw.reactors {
|
for _, reactor := range sw.reactors {
|
||||||
reactor.AddPeer(peer)
|
reactor.AddPeer(peer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,12 +68,12 @@ func (tr *TestReactor) Receive(chId byte, peer *Peer, msgBytes []byte) {
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
// convenience method for creating two switches connected to each other.
|
// convenience method for creating bar switches connected to each other.
|
||||||
func makeSwitchPair(t testing.TB, reactorsGenerator func() []Reactor) (*Switch, *Switch) {
|
func makeSwitchPair(t testing.TB, initSwitch func(*Switch) *Switch) (*Switch, *Switch) {
|
||||||
|
|
||||||
// Create two switches that will be interconnected.
|
// Create bar switches that will be interconnected.
|
||||||
s1 := NewSwitch(reactorsGenerator())
|
s1 := initSwitch(NewSwitch())
|
||||||
s2 := NewSwitch(reactorsGenerator())
|
s2 := initSwitch(NewSwitch())
|
||||||
|
|
||||||
// Create a listener for s1
|
// Create a listener for s1
|
||||||
l := NewDefaultListener("tcp", ":8001", true)
|
l := NewDefaultListener("tcp", ":8001", true)
|
||||||
@ -104,18 +104,17 @@ func makeSwitchPair(t testing.TB, reactorsGenerator func() []Reactor) (*Switch,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSwitches(t *testing.T) {
|
func TestSwitches(t *testing.T) {
|
||||||
s1, s2 := makeSwitchPair(t, func() []Reactor {
|
s1, s2 := makeSwitchPair(t, func(sw *Switch) *Switch {
|
||||||
// Make two reactors of two channels each
|
// Make bar reactors of bar channels each
|
||||||
reactors := make([]Reactor, 2)
|
sw.AddReactor("foo", NewTestReactor([]*ChannelDescriptor{
|
||||||
reactors[0] = NewTestReactor([]*ChannelDescriptor{
|
|
||||||
&ChannelDescriptor{Id: byte(0x00), Priority: 10},
|
&ChannelDescriptor{Id: byte(0x00), Priority: 10},
|
||||||
&ChannelDescriptor{Id: byte(0x01), Priority: 10},
|
&ChannelDescriptor{Id: byte(0x01), Priority: 10},
|
||||||
}, true)
|
}, true)).Start(sw) // Start the reactor
|
||||||
reactors[1] = NewTestReactor([]*ChannelDescriptor{
|
sw.AddReactor("bar", NewTestReactor([]*ChannelDescriptor{
|
||||||
&ChannelDescriptor{Id: byte(0x02), Priority: 10},
|
&ChannelDescriptor{Id: byte(0x02), Priority: 10},
|
||||||
&ChannelDescriptor{Id: byte(0x03), Priority: 10},
|
&ChannelDescriptor{Id: byte(0x03), Priority: 10},
|
||||||
}, true)
|
}, true)).Start(sw) // Start the reactor
|
||||||
return reactors
|
return sw
|
||||||
})
|
})
|
||||||
defer s1.Stop()
|
defer s1.Stop()
|
||||||
defer s2.Stop()
|
defer s2.Stop()
|
||||||
@ -129,8 +128,8 @@ func TestSwitches(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ch0Msg := "channel zero"
|
ch0Msg := "channel zero"
|
||||||
ch1Msg := "channel one"
|
ch1Msg := "channel foo"
|
||||||
ch2Msg := "channel two"
|
ch2Msg := "channel bar"
|
||||||
|
|
||||||
s1.Broadcast(byte(0x00), ch0Msg)
|
s1.Broadcast(byte(0x00), ch0Msg)
|
||||||
s1.Broadcast(byte(0x01), ch1Msg)
|
s1.Broadcast(byte(0x01), ch1Msg)
|
||||||
@ -140,7 +139,7 @@ func TestSwitches(t *testing.T) {
|
|||||||
time.Sleep(5000 * time.Millisecond)
|
time.Sleep(5000 * time.Millisecond)
|
||||||
|
|
||||||
// Check message on ch0
|
// Check message on ch0
|
||||||
ch0Msgs := s2.Reactors()[0].(*TestReactor).msgsReceived[byte(0x00)]
|
ch0Msgs := s2.Reactor("foo").(*TestReactor).msgsReceived[byte(0x00)]
|
||||||
if len(ch0Msgs) != 2 {
|
if len(ch0Msgs) != 2 {
|
||||||
t.Errorf("Expected to have received 1 message in ch0")
|
t.Errorf("Expected to have received 1 message in ch0")
|
||||||
}
|
}
|
||||||
@ -149,7 +148,7 @@ func TestSwitches(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check message on ch1
|
// Check message on ch1
|
||||||
ch1Msgs := s2.Reactors()[0].(*TestReactor).msgsReceived[byte(0x01)]
|
ch1Msgs := s2.Reactor("foo").(*TestReactor).msgsReceived[byte(0x01)]
|
||||||
if len(ch1Msgs) != 1 {
|
if len(ch1Msgs) != 1 {
|
||||||
t.Errorf("Expected to have received 1 message in ch1")
|
t.Errorf("Expected to have received 1 message in ch1")
|
||||||
}
|
}
|
||||||
@ -158,7 +157,7 @@ func TestSwitches(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check message on ch2
|
// Check message on ch2
|
||||||
ch2Msgs := s2.Reactors()[1].(*TestReactor).msgsReceived[byte(0x02)]
|
ch2Msgs := s2.Reactor("bar").(*TestReactor).msgsReceived[byte(0x02)]
|
||||||
if len(ch2Msgs) != 1 {
|
if len(ch2Msgs) != 1 {
|
||||||
t.Errorf("Expected to have received 1 message in ch2")
|
t.Errorf("Expected to have received 1 message in ch2")
|
||||||
}
|
}
|
||||||
@ -172,18 +171,17 @@ func BenchmarkSwitches(b *testing.B) {
|
|||||||
|
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
|
|
||||||
s1, s2 := makeSwitchPair(b, func() []Reactor {
|
s1, s2 := makeSwitchPair(b, func(sw *Switch) *Switch {
|
||||||
// Make two reactors of two channels each
|
// Make bar reactors of bar channels each
|
||||||
reactors := make([]Reactor, 2)
|
sw.AddReactor("foo", NewTestReactor([]*ChannelDescriptor{
|
||||||
reactors[0] = NewTestReactor([]*ChannelDescriptor{
|
|
||||||
&ChannelDescriptor{Id: byte(0x00), Priority: 10},
|
&ChannelDescriptor{Id: byte(0x00), Priority: 10},
|
||||||
&ChannelDescriptor{Id: byte(0x01), Priority: 10},
|
&ChannelDescriptor{Id: byte(0x01), Priority: 10},
|
||||||
}, false)
|
}, false))
|
||||||
reactors[1] = NewTestReactor([]*ChannelDescriptor{
|
sw.AddReactor("bar", NewTestReactor([]*ChannelDescriptor{
|
||||||
&ChannelDescriptor{Id: byte(0x02), Priority: 10},
|
&ChannelDescriptor{Id: byte(0x02), Priority: 10},
|
||||||
&ChannelDescriptor{Id: byte(0x03), Priority: 10},
|
&ChannelDescriptor{Id: byte(0x03), Priority: 10},
|
||||||
}, false)
|
}, false))
|
||||||
return reactors
|
return sw
|
||||||
})
|
})
|
||||||
defer s1.Stop()
|
defer s1.Stop()
|
||||||
defer s2.Stop()
|
defer s2.Stop()
|
||||||
@ -194,7 +192,7 @@ func BenchmarkSwitches(b *testing.B) {
|
|||||||
|
|
||||||
numSuccess, numFailure := 0, 0
|
numSuccess, numFailure := 0, 0
|
||||||
|
|
||||||
// Send random message from one channel to another
|
// Send random message from foo channel to another
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
chId := byte(i % 4)
|
chId := byte(i % 4)
|
||||||
successChan := s1.Broadcast(chId, "test data")
|
successChan := s1.Broadcast(chId, "test data")
|
||||||
|
Reference in New Issue
Block a user