func (this *ZookeeperCoordinator) AwaitOnStateBarrier(consumerId string, group string, barrierName string, barrierSize int, api string, timeout time.Duration) bool { barrierPath := fmt.Sprintf("%s/%s/%s", newZKGroupDirs(this.config.Root, group).ConsumerApiDir, api, barrierName) var barrierExpiration time.Time var err error // Block and wait for this to consumerId to join the state barrier if barrierExpiration, err = this.joinStateBarrier(barrierPath, consumerId, timeout); err == nil { // Now that we've joined the barrier wait to verify all consumers have reached consensus. membershipDoneChan := make(chan error) stopChan := make(chan struct{}) barrierTimeout := barrierExpiration.Sub(time.Now()) go this.waitForMembersToJoin(barrierPath, barrierSize, membershipDoneChan, stopChan) timeout := time.NewTimer(barrierTimeout) select { case err = <-membershipDoneChan: timeout.Stop() // break the select break case <-timeout.C: stopChan <- struct{}{} err = fmt.Errorf("Timedout waiting for consensus on barrier path %s", barrierPath) } } if err != nil { // Encountered an error waiting for consensus... Fail it Errorf(this, "Failed awaiting on state barrier %s [%v]", barrierName, err) return false } Infof(this, "Successfully awaited on state barrier %s", barrierName) return true }
func (inst *instance) Run(timeout time.Duration, command string) (<-chan []byte, <-chan error, error) { for strings.Index(command, " ") != -1 { command = strings.Replace(command, " ", " ", -1) } args := strings.Split(command, " ") cmd := exec.Command(args[0], args[1:]...) if inst.cfg.Debug { cmd.Stdout = os.Stdout cmd.Stderr = os.Stdout } if err := cmd.Start(); err != nil { return nil, nil, err } outputC := make(chan []byte, 10) errorC := make(chan error, 2) done := make(chan bool) go func() { errorC <- cmd.Wait() close(done) }() go func() { ticker := time.NewTicker(time.Second) timeout := time.NewTicker(timeout) for { select { case <-ticker.C: select { case outputC <- []byte{'.'}: default: } case <-timeout.C: errorC <- vm.TimeoutErr cmd.Process.Kill() ticker.Stop() return case <-done: ticker.Stop() timeout.Stop() return case <-inst.closed: errorC <- fmt.Errorf("closed") cmd.Process.Kill() ticker.Stop() timeout.Stop() return } } }() return outputC, errorC, nil }
func New(alloc func(size, acap int64) interface{}, size, acap int64, timeout time.Duration) (as *Pool) { as = &Pool{Take: make(chan interface{}), Give: make(chan interface{}), Size: make(chan int64), Quit: make(chan struct{}), Exit: make(chan struct{}), size: size, acap: acap} // timeout: timeout) // size: size, acap: acap} // start buffer manager go func() { q := new(list.List) for { if q.Len() == 0 { b := alloc(as.size, as.acap) //fmt.Printf("Make: len=%d, cap=%d, cnt=%d, qlen=%d\n", len(s), cap(s), as.Cnt, q.Len()) q.PushFront(qb{when: time.Now(), b: b}) as.Cnt++ } e := q.Front() timeout := time.NewTimer(as.timeout) select { case b := <-as.Give: timeout.Stop() //fmt.Printf("Give: len=%d, cap=%d, cnt=%d, qlen=%d\n", len(b), cap(b), as.Cnt, q.Len()) q.PushFront(qb{when: time.Now(), b: b}) case as.Take <- e.Value.(qb).b: //fmt.Printf("Take: cnt=%d, qlen=%d\n", as.Cnt, q.Len()) timeout.Stop() q.Remove(e) case <-timeout.C: // free unused slices older than timeout e := q.Front() for e != nil { n := e.Next() if time.Since(e.Value.(qb).when) > as.timeout { q.Remove(e) e.Value = nil } e = n } case sz := <-as.Size: // update buffer size, free buffers as.size = sz case <-as.Quit: fmt.Printf("autobuf: Cnt=%d\n", as.Cnt) as.Exit <- struct{}{} return } } }() return as }
func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command string) (<-chan []byte, <-chan error, error) { rpipe, wpipe, err := os.Pipe() if err != nil { return nil, nil, fmt.Errorf("failed to create pipe: %v", err) } for sz := 128 << 10; sz <= 2<<20; sz *= 2 { syscall.Syscall(syscall.SYS_FCNTL, wpipe.Fd(), syscall.F_SETPIPE_SZ, uintptr(sz)) } for strings.Index(command, " ") != -1 { command = strings.Replace(command, " ", " ", -1) } args := strings.Split(command, " ") cmd := exec.Command(args[0], args[1:]...) cmd.Stdout = wpipe cmd.Stderr = wpipe if err := cmd.Start(); err != nil { rpipe.Close() wpipe.Close() return nil, nil, err } wpipe.Close() outputC := make(chan []byte, 10) errorC := make(chan error, 1) done := make(chan bool) signal := func(err error) { time.Sleep(3 * time.Second) // wait for any pending output select { case errorC <- err: default: } } go func() { var buf [64 << 10]byte var output []byte for { n, err := rpipe.Read(buf[:]) if n != 0 { if inst.cfg.Debug { os.Stdout.Write(buf[:n]) os.Stdout.Write([]byte{'\n'}) } output = append(output, buf[:n]...) select { case outputC <- output: output = nil default: } time.Sleep(time.Millisecond) } if err != nil { rpipe.Close() return } } }() go func() { err := cmd.Wait() signal(err) close(done) }() go func() { timeout := time.NewTicker(timeout) for { select { case <-timeout.C: signal(vm.TimeoutErr) cmd.Process.Kill() return case <-stop: signal(vm.TimeoutErr) cmd.Process.Kill() timeout.Stop() return case <-done: timeout.Stop() return case <-inst.closed: signal(fmt.Errorf("closed")) cmd.Process.Kill() timeout.Stop() return } } }() return outputC, errorC, nil }