Пример #1
0
func NewList() List {
	list := make([]*Agent, state.NodeCount())
	for i := 0; i < state.NodeCount(); i++ {
		list[i] = NewAgent(uint(i))
	}
	return list
}
Пример #2
0
func New() *Network {
	count := uint(state.NodeCount())
	net := &Network{
		links: make([]*Link, 0),
		cache: make([][]*Link, count),
	}

	var i, j, offset uint
	for i = 0; i < count; i++ {
		for j = 0; j < i; j++ {
			link := &Link{
				network: net,
				kill:    make(chan bool),
				// Do smaller number as agent1
				agent1: j,
				agent2: i,
			}
			net.links = append(net.links, link)
		}
	}

	for offset, i = 0, 0; i < count; offset, i = offset+i, i+1 {
		net.cache[i] = net.links[offset : offset+i]
	}

	return net
}
Пример #3
0
// SpofMonkey detects single points of failure by netsplitting one node at a
// time away from the rest of the cluster and ensuring that the cluster
// continues to make progress.
func (d *Director) SpofMonkey(rng *rand.Rand, intensity float64) bool {
	if spofIndex >= state.NodeCount() {
		return false
	} else if len(spofOrder) != state.NodeCount() {
		// Unfortunately we can't do this in an init() because we defer
		// the parsing of flag arguments until later.
		spofOrder = rng.Perm(state.NodeCount())
	}

	i := spofOrder[spofIndex]
	log.Printf("[monkey] Testing if %v is a single point of failure",
		d.agents[i])

	netsplit := d.net.FindPerimeter([]uint{uint(i)})
	spofIndex++

	d.agents[i].Freeze()

	for _, target := range netsplit {
		target.GoodbyeForever()
	}

	// We need to make sure that the cluster is capable of servicing
	// requests that no member of the cluster has ever seen before in order
	// to ensure that the cluster is making progress. To do this, we
	// determine the request ID of the last request that has been created,
	// and make sure that we see a request that was created *after* that
	// (any requests generated after targetRequestId were necessarily
	// generated after the actions above).
	targetRequestId := state.LastGeneratedRequest()
	for <-state.GotRequest() <= targetRequestId {
	}

	log.Printf("[monkey] %v is (probably) not a single point of failure!",
		d.agents[i])

	for _, target := range netsplit {
		target.WhyHelloThere()
	}

	d.agents[i].Thaw()

	return true
}
Пример #4
0
// Choose random connections such that each node has a connection in the
// returned list.
func (d *Director) randomNeighborLinks(rng *rand.Rand) []*network.Link {
	links := d.net.Links()
	perm := rng.Perm(len(links))

	cover := make(map[uint]bool, state.NodeCount())
	for i := 0; i < state.NodeCount(); i++ {
		cover[uint(i)] = false
	}
	out := make([]*network.Link, 0, (state.NodeCount()+1)/2)

	for _, i := range perm {
		link := links[i]
		a1, a2 := link.Agents()
		if !cover[a1] || !cover[a2] {
			out = append(out, link)
			cover[a1] = true
			cover[a2] = true
		}
	}
	return out
}
Пример #5
0
func (d *Director) randomPartition(rng *rand.Rand) []*network.Link {
	count := state.NodeCount()

	// If there are fewer than three nodes, netsplits are pretty
	// boring
	if count < 3 {
		return []*network.Link{d.net.Links()[0]}
	}
	perm := rng.Perm(count)
	splitPoint := rng.Intn(count-2) + 1
	split := make([]uint, 0)
	for i := 0; i < splitPoint; i++ {
		split = append(split, uint(perm[i]))
	}
	log.Debugf("Made a netsplit: %v", split)
	return d.net.FindPerimeter(split)
}
Пример #6
0
func (h *Harness) startQueryThreads() {
	threads := 4 * state.NodeCount()
	for i := 0; i < threads; i++ {
		go h.queryThread()
	}
}