func (t *packetTransport) sendLoop() { defer t.logger.Printf("packet transport: send loop exit") for msg := range t.outgoingc { b, err := msg.Marshal() if err != nil { t.logger.Printf("packet transport: send to Raft ID %x: %v (continuing)", msg.To, err) continue } peerName, err := t.translate(mesh.PeerUID(msg.To)) if err != nil { select { case t.unreachablec <- msg.To: t.logger.Printf("packet transport: send to Raft ID %x: %v (unreachable; continuing) (%s)", msg.To, err, msg.Type) default: t.logger.Printf("packet transport: send to Raft ID %x: %v (unreachable, report dropped; continuing) (%s)", msg.To, err, msg.Type) } continue } dst := meshconn.MeshAddr{PeerName: peerName} if n, err := t.conn.WriteTo(b, dst); err != nil { t.logger.Printf("packet transport: send to Mesh peer %s: %v (continuing)", dst, err) continue } else if n < len(b) { t.logger.Printf("packet transport: send to Mesh peer %s: short write, %d < %d (continuing)", dst, n, len(b)) continue } //t.logger.Printf("packet transport: send to %s (sz %d/%d) OK", dst, msg.Size(), len(b)) } }
func makeAllocator(name string, cidrStr string, quorum uint) (*Allocator, address.Range) { peername, err := mesh.PeerNameFromString(name) if err != nil { panic(err) } _, cidr, err := address.ParseCIDR(cidrStr) if err != nil { panic(err) } alloc := NewAllocator(peername, mesh.PeerUID(rand.Int63()), "nick-"+name, cidr.Range(), quorum, func(mesh.PeerName) bool { return true }) return alloc, cidr.HostRange() }
// Restart a node func (m *Model) restart(node *TestNode) { node.Node = NewNode(mesh.PeerName(m.nextID), mesh.PeerUID(m.r.Int63()), m.quorum) m.nextID++ node.Propose() // The node is now ignorant, so we need to mark the links into // the node as ready. for _, l := range node.links { if !l.to.isolated { m.readyLink(l.converse) } } // If a consensus was just accepted due to this node accepting // it, without other nodes hearing of it, and we then restart // this node, then a different consensus can occur later on. // If a tree falls with no one to hear it, does it make a // sound? node.firstConsensus = AcceptedValue{} }
// Make a network of nodes with random topology func makeRandomModel(params *TestParams, r *rand.Rand, t *testing.T) *Model { m := Model{ t: t, r: r, quorum: params.nodeCount/2 + 1, nodes: make([]TestNode, params.nodeCount), readyLinks: []*Link{}, nextID: params.nodeCount + 1, } for i := range m.nodes { m.nodes[i].Node = NewNode(mesh.PeerName(i/2+1), mesh.PeerUID(r.Int63()), m.quorum) m.nodes[i].Propose() } for i := 1; i < len(m.nodes); i++ { // was node i connected to the other nodes yet? connected := false for j := 0; j < i; j++ { if r.Float32() < params.connectedProb { connected = true m.addLink(&m.nodes[i], &m.nodes[j]) } } if !connected { // node i must be connected into the graph // somewhere. So if we didn't connect it // already, this is a last resort. m.addLink(&m.nodes[i], &m.nodes[r.Intn(i)]) } } return &m }