Merge pull request #886 from bboreham/885-gossip-race

Avoid gossip test race conditions

Fixes #885.
This commit is contained in:
Matthias Radestock committed 2015-06-10 13:50:40 +01:00
commit 0ab7c31bbe
2 files changed
+26 -17

No files matched your search

+24 -16
View File
@@ -39,8 +39,9 @@ type Gossiper interface {
// Accumulates GossipData that needs to be sent to one destination,
// and sends it when possible.
type GossipSender struct {
send func(GossipData)
cell chan GossipData
send func(GossipData)
cell chan GossipData
flushch chan chan struct{}
}
func NewGossipSender(send func(GossipData)) *GossipSender {
@@ -49,15 +50,28 @@ func NewGossipSender(send func(GossipData)) *GossipSender {
func (sender *GossipSender) Start() {
sender.cell = make(chan GossipData, 1)
sender.flushch = make(chan chan struct{})
go sender.run()
}
func (sender *GossipSender) run() {
for {
if pending := <-sender.cell; pending == nil { // receive zero value when chan is closed
break
} else {
select {
case pending := <-sender.cell:
if pending == nil { // receive zero value when chan is closed
return
}
sender.send(pending)
case ch := <-sender.flushch:
// ensure anything pending is sent, then close the channel we were given
select {
case pending := <-sender.cell:
if pending != nil {
sender.send(pending)
}
default:
}
close(ch)
}
}
}
@@ -314,27 +328,21 @@ func (c *GossipChannel) log(args ...interface{}) {
// for testing
// FIXME this doesn't actually guarantee everything has been sent
// since a GossipSender may be in the process of sending and there is
// no easy way for us to know when that has completed.
func (router *Router) sendPendingGossip() {
for _, channel := range router.GossipChannels {
channel.Lock()
for _, sender := range channel.senders {
sender.flush()
}
for _, sender := range channel.broadcasters {
sender.flush()
}
channel.Unlock()
}
}
func (sender *GossipSender) flush() {
for {
select {
case pending := <-sender.cell:
sender.send(pending)
default:
return
}
}
ch := make(chan struct{})
sender.flushch <- ch
<-ch
}
+2 -1
View File
@@ -30,7 +30,6 @@ func (conn *mockChannelConnection) SendProtocolMsg(protocolMsg ProtocolMsg) {
if err := conn.dest.handleGossip(protocolMsg.tag, protocolMsg.msg); err != nil {
panic(err)
}
conn.dest.sendPendingGossip()
}
func (router *Router) AddTestChannelConnection(r *Router) {
@@ -87,7 +86,9 @@ func (router *Router) tp(routers ...*Router) *Peer {
// Check that the topology of router matches the peers and all of their connections
func checkTopology(t *testing.T, router *Router, wantedPeers ...*Peer) {
router.Peers.RLock()
checkTopologyPeers(t, true, router.Peers.allPeers(), wantedPeers...)
router.Peers.RUnlock()
}
func implTestGossipTopology(t *testing.T) {