Beispiel #1
0
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
}
Beispiel #2
0
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
}
Beispiel #3
0
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
}
Beispiel #4
0
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
}