func (grouter *TestRouter) run(sender router.PeerName, gossiper router.Gossiper, gossipChan chan interface{}) { gossipTimer := time.Tick(10 * time.Second) for { select { case gossip := <-gossipChan: switch message := gossip.(type) { case exitMessage: close(message.exitChan) return case flushMessage: close(message.flushChan) case unicastMessage: if rand.Float32() > (1.0 - grouter.loss) { continue } if err := gossiper.OnGossipUnicast(message.sender, message.buf); err != nil { panic(fmt.Sprintf("Error doing gossip unicast to %s: %s", message.sender, err)) } case broadcastMessage: if rand.Float32() > (1.0 - grouter.loss) { continue } for _, msg := range message.data.Encode() { if _, err := gossiper.OnGossipBroadcast(message.sender, msg); err != nil { panic(fmt.Sprintf("Error doing gossip broadcast: %s", err)) } } case gossipMessage: if rand.Float32() > (1.0 - grouter.loss) { continue } for _, msg := range message.data.Encode() { diff, err := gossiper.OnGossip(msg) if err != nil { panic(fmt.Sprintf("Error doing gossip: %s", err)) } if diff == nil { continue } // Sanity check - reconsuming the diff should yield nil for _, diffMsg := range diff.Encode() { if nextDiff, err := gossiper.OnGossip(diffMsg); err != nil { panic(fmt.Sprintf("Error doing gossip: %s", err)) } else if nextDiff != nil { panic(fmt.Sprintf("Breach of gossip interface: %v != nil", nextDiff)) } } grouter.gossip(message.sender, diff) } } case <-gossipTimer: grouter.gossip(sender, gossiper.Gossip()) } } }
func (grouter *TestRouter) run(sender router.PeerName, gossiper router.Gossiper, gossipChan chan interface{}) { gossipTimer := time.Tick(10 * time.Second) for { select { case gossip := <-gossipChan: switch message := gossip.(type) { case exitMessage: close(message.exitChan) return case flushMessage: close(message.flushChan) case unicastMessage: if rand.Float32() > (1.0 - grouter.loss) { continue } if err := gossiper.OnGossipUnicast(message.sender, message.buf); err != nil { panic(fmt.Sprintf("Error doing gossip unicast to %s: %s", message.sender, err)) } case broadcastMessage: if rand.Float32() > (1.0 - grouter.loss) { continue } for _, msg := range message.data.Encode() { // TODO: this should call OnGossipBroadcast, and we should implement // 'trickle' gossip correctly in this mock. But no one depends on this // difference for testing right now, so we abuse the interface here. diff, err := gossiper.OnGossip(msg) if err != nil { panic(fmt.Sprintf("Error doing gossip broadcast: %s", err)) } if diff == nil { continue } // Sanity check - reconsuming the diff should yield nil for _, diffMsg := range diff.Encode() { if nextDiff, err := gossiper.OnGossip(diffMsg); err != nil { panic(fmt.Sprintf("Error doing gossip broadcast: %s", err)) } else if nextDiff != nil { panic(fmt.Sprintf("Breach of gossip interface: %v != nil", nextDiff)) } } } } case <-gossipTimer: grouter.gossipBroadcast(sender, gossiper.Gossip()) } } }