// WatchServiceLock waits for a service lock to be enabled/disabled func WaitServiceLock(shutdown <-chan interface{}, conn client.Connection, enabled bool) error { for { // make sure the parent exists if err := zzk.Ready(shutdown, conn, zkServiceLock); err != nil { return err } // check if the lock is enabled nodes, event, err := conn.ChildrenW(zkServiceLock) if err != nil { return err } // check that the states match if locked := len(nodes) > 0; locked == enabled { return nil } // wait to reach the desired state or shutdown select { case <-event: // pass case <-shutdown: return zzk.ErrTimeout } } }
func MonitorResourcePool(shutdown <-chan interface{}, conn client.Connection, poolID string) <-chan *pool.ResourcePool { monitor := make(chan *pool.ResourcePool) go func() { defer close(monitor) if err := zzk.Ready(shutdown, conn, poolpath(poolID)); err != nil { glog.V(2).Infof("Could not watch pool %s: %s", poolID, err) return } for { var node PoolNode event, err := conn.GetW(poolpath(poolID), &node) if err != nil { glog.V(2).Infof("Could not get pool %s: %s", poolID, err) return } select { case monitor <- node.ResourcePool: case <-shutdown: return } select { case <-event: case <-shutdown: return } } }() return monitor }
func (l *ServiceLockListener) Spawn(shutdown <-chan interface{}, poolID string) { lock := l.conn.NewLock(l.GetPath(poolID, zkServiceLock)) defer lock.Unlock() for { if err := zzk.Ready(shutdown, l.conn, zkServiceLock); err != nil { glog.V(2).Infof("Could not monitor lock: %s", err) return } nodes, lockEvent, err := l.conn.ChildrenW(zkServiceLock) if err != nil { glog.V(2).Infof("Could not monitor lock: %s", err) return } poolEvent, err := l.conn.GetW(l.GetPath(poolID), &PoolNode{}) if err != nil { glog.V(2).Infof("Could not look up node for pool %s: %s", poolID, err) return } if len(nodes) > 0 { glog.V(3).Infof("Engaging service lock for %s", poolID) lock.Lock() } else { glog.V(3).Infof("Disengaging service lock for %s", poolID) lock.Unlock() } select { case <-lockEvent: // pass case e := <-poolEvent: if e.Type == client.EventNodeDeleted { return } case <-shutdown: return } } }