// Find possible addresses for cluster named name. func lookup(b *doozer.Conn, name string) (as []string) { rev, err := b.Rev() if err != nil { panic(err) } path := "/ctl/ns/" + name names, err := b.Getdir(path, rev, 0, -1) if err == doozer.ErrNoEnt { return nil } else if err, ok := err.(*doozer.Error); ok && err.Err == doozer.ErrNoEnt { return nil } else if err != nil { panic(err) } path += "/" for _, name := range names { body, _, err := b.Get(path+name, &rev) if err != nil { panic(err) } as = append(as, string(body)) } return as }
// watch updates the peer list of servers based on changes to the // doozer configuration or signals from the OS. func watch(d *doozer.Conn) { peerFile := "/peers" var peers []string var rev int64 // Run the initial get. data, rev, err := d.Get(peerFile, nil) if err != nil { log.Println("initial peer list get:", err) log.Println("using empty set to start") peers = []string{} } else { peers = strings.Split(string(data), " ") } // Add myself to the list. peers = append(peers, "http://"+addr) rev, err = d.Set(peerFile, rev, []byte(strings.Join(peers, " "))) if err != nil { log.Println("unable to add myself to the peer list (no longer watching).") return } pool.Set(peers...) log.Println("added myself to the peer list.") // Setup signal handling to deal with ^C and others. sigs := make(chan os.Signal, 1) signal.Notify(sigs, os.Interrupt, os.Kill) // Get the channel that's listening for changes. updates := wait(d, peerFile, &rev) for { select { case <-sigs: // Remove ourselves from the peer list and exit. for i, peer := range peers { if peer == "http://"+addr { peers = append(peers[:i], peers[i+1:]...) d.Set(peerFile, rev, []byte(strings.Join(peers, " "))) log.Println("removed myself from peer list before exiting.") } } os.Exit(1) case update, ok := <-updates: // If the channel was closed, we should stop selecting on it. if !ok { updates = nil continue } // Otherwise, update the peer list. peers = update log.Println("got new peer list:", strings.Join(peers, " ")) pool.Set(peers...) } } }