func (s *ReconSuite) pollConvergence(c *gc.C, peer1, peer2 *recon.Peer, peer1Needs, peer2Needs *cf.ZSet, timeout time.Duration) error { var t tomb.Tomb t.Go(func() error { defer peer1.Stop() defer peer2.Stop() timer := time.NewTimer(timeout) POLLING: for { select { case r1, ok := <-peer1.RecoverChan: if !ok { break POLLING } c.Logf("peer1 recover: %v", r1) peer1.Insert(r1.RemoteElements...) peer1Needs.RemoveSlice(r1.RemoteElements) case r2, ok := <-peer2.RecoverChan: if !ok { break POLLING } c.Logf("peer2 recover: %v", r2) peer2.Insert(r2.RemoteElements...) peer2Needs.RemoveSlice(r2.RemoteElements) case _ = <-timer.C: c.Log("peer1 still needed ", peer1Needs.Len(), ":", peer1Needs) c.Log("peer2 still needed ", peer2Needs.Len(), ":", peer2Needs) return fmt.Errorf("timeout waiting for convergence") default: } if peer1Needs.Len() == 0 && peer2Needs.Len() == 0 { c.Log("all done!") return nil } time.Sleep(ShortDelay) } return fmt.Errorf("set reconciliation did not converge") }) return t.Wait() }
func (s *ReconSuite) pollRootConvergence(c *gc.C, peer1, peer2 *recon.Peer, ptree1, ptree2 recon.PrefixTree) error { var t tomb.Tomb t.Go(func() error { defer peer1.Stop() defer peer2.Stop() var mu sync.Mutex var zs1 *cf.ZSet = cf.NewZSet() var zs2 *cf.ZSet = cf.NewZSet() timer := time.NewTimer(LongTimeout) peer1.SetMutatedFunc(func() { mu.Lock() root1, err := ptree1.Root() c.Assert(err, gc.IsNil) zs1 = cf.NewZSet(recon.MustElements(root1)...) mu.Unlock() }) peer2.SetMutatedFunc(func() { mu.Lock() root2, err := ptree2.Root() c.Assert(err, gc.IsNil) zs2 = cf.NewZSet(recon.MustElements(root2)...) mu.Unlock() }) POLLING: for { select { case r1, ok := <-peer1.RecoverChan: if !ok { break POLLING } c.Logf("peer1 recover: %v", r1) for _, zp := range r1.RemoteElements { c.Assert(zp, gc.NotNil) peer1.Insert(zp) } case r2, ok := <-peer2.RecoverChan: if !ok { break POLLING } c.Logf("peer2 recover: %v", r2) for _, zp := range r2.RemoteElements { c.Assert(zp, gc.NotNil) peer2.Insert(zp) } case _ = <-timer.C: return fmt.Errorf("timeout waiting for convergence") default: } var done bool mu.Lock() done = zs1.Len() > 0 && zs1.Equal(zs2) mu.Unlock() if done { c.Logf("peer1 has %q, peer2 has %q", zs1, zs2) return nil } } return fmt.Errorf("set reconciliation did not converge") }) return t.Wait() }