Ejemplo n.º 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()
}