// SimulateNetwork runs until the simCallback returns false. // // At each cycle, every node gossips a key equal to its address (unique) // with the cycle as the value. The received cycle value can be used // to determine the aging of information between any two nodes in the // network. // // At each cycle of the simulation, node 0 gossips the sentinel. // // The simulation callback receives the cycle and the network as arguments. func (n *Network) SimulateNetwork(simCallback func(cycle int, network *Network) bool) { nodes := n.Nodes for cycle := 1; simCallback(cycle, n); cycle++ { // Node 0 gossips sentinel & cluster ID every cycle. if err := nodes[0].Gossip.AddInfo( gossip.KeySentinel, encoding.EncodeUint64Ascending(nil, uint64(cycle)), time.Hour); err != nil { log.Fatal(err) } if err := nodes[0].Gossip.AddInfo(gossip.KeyClusterID, encoding.EncodeUint64Ascending(nil, uint64(cycle)), 0*time.Second); err != nil { log.Fatal(err) } // Every node gossips cycle. for _, node := range nodes { if err := node.Gossip.AddInfo( node.Addr.String(), encoding.EncodeUint64Ascending(nil, uint64(cycle)), time.Hour); err != nil { log.Fatal(err) } node.Gossip.SimulationCycle() } time.Sleep(5 * time.Millisecond) } log.Infof("gossip network simulation: total infos sent=%d, received=%d", n.infosSent(), n.infosReceived()) }
func generateUniqueBytes(nodeID roachpb.NodeID) DBytes { // Unique bytes are composed of the current time in nanoseconds and the // node-id. If the nanosecond value is the same on two consecutive calls to // timeutil.Now() the nanoseconds value is incremented. The node-id is varint // encoded. Since node-ids are allocated consecutively starting at 1, the // node-id field will consume 1 or 2 bytes for any reasonably sized cluster. // // TODO(pmattis): Do we have to worry about persisting the milliseconds value // periodically to avoid the clock ever going backwards (e.g. due to NTP // adjustment)? nanos := uint64(timeutil.Now().UnixNano()) uniqueBytesState.Lock() if nanos <= uniqueBytesState.nanos { nanos = uniqueBytesState.nanos + 1 } uniqueBytesState.nanos = nanos uniqueBytesState.Unlock() b := make([]byte, 0, 8+binary.MaxVarintLen32) b = encoding.EncodeUint64Ascending(b, nanos) // We use binary.PutUvarint instead of encoding.EncodeUvarint because the // former uses less space for values < 128 which is a common occurrence for // node IDs. n := binary.PutUvarint(b[len(b):len(b)+binary.MaxVarintLen32], uint64(nodeID)) return DBytes(b[:len(b)+n]) }
// StartNode initializes a gossip instance for the simulation node and // starts it. func (n *Network) StartNode(node *Node) error { n.nodeIDAllocator++ node.Gossip.SetNodeID(n.nodeIDAllocator) if err := node.Gossip.SetNodeDescriptor(&roachpb.NodeDescriptor{ NodeID: node.Gossip.GetNodeID(), Address: util.MakeUnresolvedAddr(node.Addr.Network(), node.Addr.String()), }); err != nil { return err } if err := node.Gossip.AddInfo(node.Addr.String(), encoding.EncodeUint64Ascending(nil, 0), time.Hour); err != nil { return err } node.Gossip.Start(node.Server, node.Addr) node.Gossip.EnableSimulationCycler(true) return nil }
// StartNode initializes a gossip instance for the simulation node and // starts it. func (n *Network) StartNode(node *Node) error { node.Gossip.Start(node.Addr()) node.Gossip.EnableSimulationCycler(true) n.nodeIDAllocator++ node.Gossip.SetNodeID(n.nodeIDAllocator) if err := node.Gossip.SetNodeDescriptor(&roachpb.NodeDescriptor{ NodeID: node.Gossip.GetNodeID(), Address: util.MakeUnresolvedAddr(node.Addr().Network(), node.Addr().String()), }); err != nil { return err } if err := node.Gossip.AddInfo(node.Addr().String(), encoding.EncodeUint64Ascending(nil, 0), time.Hour); err != nil { return err } n.Stopper.RunWorker(func() { netutil.FatalIfUnexpected(node.Server.Serve(node.Listener)) }) return nil }
// SetFloat encodes the specified float64 value into the bytes field of the // receiver, sets the tag and clears the checksum. func (v *Value) SetFloat(f float64) { v.RawBytes = make([]byte, headerSize+8) encoding.EncodeUint64Ascending(v.RawBytes[headerSize:headerSize], math.Float64bits(f)) v.setTag(ValueType_FLOAT) }
// EncodeFloatValue encodes a float value, appends it to the supplied buffer, // and returns the final buffer. func EncodeFloatValue(appendTo []byte, f float64) []byte { appendTo = append(appendTo, byte(ValueType_FLOAT)) return encoding.EncodeUint64Ascending(appendTo, math.Float64bits(f)) }
// RaftLogKey returns a system-local key for a Raft log entry. func RaftLogKey(rangeID roachpb.RangeID, logIndex uint64) roachpb.Key { key := RaftLogPrefix(rangeID) key = encoding.EncodeUint64Ascending(key, logIndex) return key }
// RaftLogKey returns a system-local key for a Raft log entry. func RaftLogKey(rangeID roachpb.RangeID, logIndex uint64) roachpb.Key { return MakeRangeIDKey(rangeID, localRaftLogSuffix, encoding.EncodeUint64Ascending(nil, logIndex)) }
// RaftLogKey returns a system-local key for a Raft log entry. func RaftLogKey(rangeID roachpb.RangeID, logIndex uint64) roachpb.Key { key := MakeRangeIDKey(rangeID, localRaftLogSuffix, nil) key = encoding.EncodeUint64Ascending(key, logIndex) return key }