Example #1
0
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()
}
Example #2
0
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()
}