예제 #1
0
func GetHostID(conn client.Connection, ip string) (string, error) {
	leader := zzk.NewHostLeader(conn, "", "", vippath(ip))
	return zzk.GetHostID(leader)
}
예제 #2
0
// Spawn implements zzk.Listener
func (l *VirtualIPListener) Spawn(shutdown <-chan interface{}, ip string) {
	// ensure that the retry sentinel has good initial state
	if l.retry == nil {
		l.retry = make(map[string]int)
	}
	if _, ok := l.retry[ip]; !ok {
		l.retry[ip] = maxRetries
	}

	// Check if this ip has exceeded the number of retries for this host
	if l.retry[ip] > maxRetries {
		glog.Warningf("Throttling acquisition of %s for %s", ip, l.hostID)
		select {
		case <-time.After(waitTimeout):
		case <-shutdown:
			return
		}
	}

	glog.V(2).Infof("Host %s waiting to acquire virtual ip %s", l.hostID, ip)
	// Try to take lead on the path
	leader := zzk.NewHostLeader(l.conn, l.hostID, "", l.GetPath(ip))
	_, err := leader.TakeLead()
	if err != nil {
		glog.Errorf("Error while trying to acquire a lock for %s: %s", ip, err)
		return
	}
	defer l.stopInstances(ip)
	defer leader.ReleaseLead()

	select {
	case <-shutdown:
		return
	default:
	}

	// Check if the path still exists
	if exists, err := zzk.PathExists(l.conn, l.GetPath(ip)); err != nil {
		glog.Errorf("Error while checking ip %s: %s", ip, err)
		return
	} else if !exists {
		return
	}

	index := l.getIndex()
	for {
		var vip pool.VirtualIP
		event, err := l.conn.GetW(l.GetPath(ip), &VirtualIPNode{VirtualIP: &vip})
		if err == client.ErrEmptyNode {
			glog.Errorf("Deleting empty node for ip %s", ip)
			RemoveVirtualIP(l.conn, ip)
			return
		} else if err != nil {
			glog.Errorf("Could not load virtual ip %s: %s", ip, err)
			return
		}

		glog.V(2).Infof("Host %s binding to %s", l.hostID, ip)
		rebind, err := l.bind(&vip, index)
		if err != nil {
			glog.Errorf("Could not bind to virtual ip %s: %s", ip, err)
			l.retry[ip]++
			return
		}

		if l.retry[ip] > 0 {
			l.retry[ip]--
		}

		select {
		case e := <-event:
			// If the virtual ip is changed, you need to update the bindings
			if err := l.unbind(ip); err != nil {
				glog.Errorf("Could not unbind to virtual ip %s: %s", ip, err)
				return
			}
			if e.Type == client.EventNodeDeleted {
				return
			}
			glog.V(4).Infof("virtual ip listener for %s receieved event: %v", ip, e)
		case <-rebind:
			// If the primary virtual IP is removed, all other virtual IPs on
			// that subnet are removed.  This is in place to restore the
			// virtual IPs that were removed soley by the removal of the
			// primary virtual IP.
			glog.V(2).Infof("Host %s rebinding to %s", l.hostID, ip)
		case <-shutdown:
			if err := l.unbind(ip); err != nil {
				glog.Errorf("Could not unbind to virtual ip %s: %s", ip, err)
			}
			return
		}
	}
}