func GetHostID(conn client.Connection, ip string) (string, error) { leader := zzk.NewHostLeader(conn, "", "", vippath(ip)) return zzk.GetHostID(leader) }
// 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 } } }