func WaitFreeTask(client *etcd.Client, name string, logger *log.Logger) (uint64, error) {
	slots, err := client.Get(FreeTaskDir(name), false, true)
	if err != nil {
		return 0, err
	}
	if total := len(slots.Node.Nodes); total > 0 {
		ri := rand.Intn(total)
		s := slots.Node.Nodes[ri]
		idStr := path.Base(s.Key)
		id, err := strconv.ParseUint(idStr, 0, 64)
		if err != nil {
			return 0, err
		}
		logger.Printf("got free task %v, randomly choose %d to try...", ListKeys(slots.Node.Nodes), ri)
		return id, nil
	}

	watchIndex := slots.EtcdIndex + 1
	respChan := make(chan *etcd.Response, 1)
	go func() {
		for {
			logger.Printf("start to wait failure at index %d", watchIndex)
			resp, err := client.Watch(FreeTaskDir(name), watchIndex, true, nil, nil)
			if err != nil {
				logger.Printf("WARN: WaitFailure watch failed: %v", err)
				return
			}
			if resp.Action == "set" {
				respChan <- resp
				return
			}
			watchIndex = resp.EtcdIndex + 1
		}
	}()
	var resp *etcd.Response
	select {
	case resp = <-respChan:
	case <-time.After(10 * time.Second):
		return 0, fmt.Errorf("WaitFailure timeout!")
	}
	idStr := path.Base(resp.Node.Key)
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil {
		return 0, err
	}
	return id, nil
}
// WaitFreeTask blocks until it gets a hint of free task
WaitFreeTask blocks until it gets a hint of free task
// WaitFreeTask blocks until it gets a hint of free task
func WaitFreeTask(client *etcd.Client, name string, logger *log.Logger) (uint64, error) {
	slots, err := client.Get(FreeTaskDir(name), false, true)
	if err != nil {
		return 0, err
	}
	if total := len(slots.Node.Nodes); total > 0 {
		ri := rand.Intn(total)
		s := slots.Node.Nodes[ri]
		idStr := path.Base(s.Key)
		id, err := strconv.ParseUint(idStr, 0, 64)
		if err != nil {
			return 0, err
		}
		logger.Printf("got free task %v, randomly choose %d to try...", ListKeys(slots.Node.Nodes), ri)
		return id, nil
	}
	watchIndex := slots.EtcdIndex + 1
	respChan := make(chan *etcd.Response, 1)
	go func() {
		for {
			logger.Printf("start to wait failure at index %d", watchIndex)
			resp, err := client.Watch(FreeTaskDir(name), watchIndex, true, nil, nil)
			if err != nil {
				logger.Printf("WARN: WaitFailure watch failed: %v", err)
				return
			}
			if resp.Action == "set" {
				respChan <- resp
				return
			}
			watchIndex = resp.EtcdIndex + 1
		}
	}()
	var resp *etcd.Response
	select {
	case resp = <-respChan:
	case <-time.After(10 * time.Second):
		return 0, fmt.Errorf("WaitFailure timeout!")
	}
	idStr := path.Base(resp.Node.Key)
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil {
		return 0, err
	}
	return id, nil
}
func WaitFreeTask ( client * etcd . Client , name string , logger * log . Logger ) ( uint64 , error ) { slots , err := client . Get ( FreeTaskDir ( name ) , false , true ) if err != nil { return 0 , err } if total := len ( slots . Node . Nodes ) ; total > 0 { ri := rand . Intn ( total ) s := slots . Node . Nodes [ ri ] idStr := path . Base ( s . Key ) id , err := strconv . ParseUint ( idStr , 0 , 64 ) if err != nil { return 0 , err } logger . Printf ( " " , ListKeys ( slots . Node . Nodes ) , ri ) return id , nil } watchIndex := slots . EtcdIndex + 1 respChan := make ( chan * etcd . Response , 1 ) go func ( ) { for { logger . Printf ( " " , watchIndex ) resp , err := client . Watch ( FreeTaskDir ( name ) , watchIndex , true , nil , nil ) if err != nil { logger . Printf ( " " , err ) return } if resp . Action == " " { respChan <- resp return } watchIndex = resp . EtcdIndex + 1 } } ( ) var resp * etcd . Response select { case resp = <- respChan : case <- time . After ( 10 * time . Second ) : return 0 , fmt . Errorf ( " " ) } idStr := path . Base ( resp . Node . Key ) id , err := strconv . ParseUint ( idStr , 10 , 64 ) if err != nil { return 0 , err } return id , nil }
WaitFreeTask blocks until it gets a hint of free task
WaitFreeTask blocks until it gets a hint of free task