go wait_tcp


原文链接: go wait_tcp
#!/bin/bash
# Variables
WERCKER_STEP_WAIT_TCP_HOST=${WERCKER_STEP_WAIT_TCP_HOST:-localhost}
WERCKER_STEP_WAIT_TCP_PORT=${WERCKER_STEP_WAIT_TCP_PORT:-8080}
WERCKER_STEP_WAIT_TCP_TIMEOUT=${WERCKER_STEP_WAIT_TCP_TIMEOUT:-60}

function waitTcp {
  while ! nc -q 1 $WERCKER_STEP_WAIT_TCP_HOST $WERCKER_STEP_WAIT_TCP_PORT </dev/null; do
    sleep 1
    let "WERCKER_STEP_WAIT_TCP_TIMEOUT--"
    if [[ "$WERCKER_STEP_WAIT_TCP_TIMEOUT" == "0" ]]; then
      exit 1
    fi
    echo "waiting for $WERCKER_STEP_WAIT_TCP_HOST:$WERCKER_STEP_WAIT_TCP_PORT $WERCKER_STEP_WAIT_TCP_TIMEOUT"
  done 
}
// waitTCP wait until the TCP service is accepting connections
//
// It times out and panics after 60 seconds.
func waitTCP(addr string) {
	log.Printf("Waiting for TCP to be available at %s", addr)
	// Try once a second to connect
	for startTime := time.Now(); time.Since(startTime) < 10*time.Second; time.Sleep(time.Second) {
		conn, err := net.DialTimeout("tcp", addr, time.Second)

		if err == nil {
			// Connection successful
			log.Printf("TCP came up on %s", addr)
			closeErr := conn.Close()
			if closeErr != nil {
				log.Printf("Error closing TCP connection in waitTCP: %s", closeErr)
			}

			return
		}

		log.Printf("Tried to connect to %s, got error: %s. Will retry in 1 second.", addr, err)
	}

	// Timed out
	panic(fmt.Sprintf("Timeout out waiting for service to start on %s", addr))
}

// waitTCP wait until the TCP service is not accepting connections
//
// It times out and panics after 60 seconds.
func waitTCPDown(addr string) {
	log.Printf("Waiting for TCP to be down at %s", addr)
	// Try once a second to connect
	for startTime := time.Now(); time.Since(startTime) < 10*time.Second; time.Sleep(time.Second) {
		conn, err := net.DialTimeout("tcp", addr, time.Second)

		if err != nil {
			// Connection failed
			log.Printf("TCP went down on %s", addr)
			return
		}

		closeErr := conn.Close()
		if closeErr != nil {
			log.Printf("Error closing TCP connection in waitTCP: %s", closeErr)
		}

		log.Printf("Tried to connect to %s, was successful. Will retry in 1 second.", addr)
	}

	// Timed out
	panic(fmt.Sprintf("Timeout out waiting for service to stop on %s", addr))
}
func waitForPort(ctx context.Context, host string, port int) (err error) {
	var conn net.Conn
	for conn == nil {
		select {
		case <-ctx.Done():
			return ctx.Err()
		case <-time.After(5 * time.Second):
			conn, err = net.Dial("tcp", fmt.Sprintf("%s:%d", host, port))
		}
	}
	conn.Close()
	return err
}

等待文件可读

// WaitUntilRead reads from the given reader until the wanted string is found
// or until timeout.
func WaitUntilRead(r io.Reader, want string, split bufio.SplitFunc, timeout time.Duration) error {
	sc := bufio.NewScanner(r)
	if split != nil {
		sc.Split(split)
	}
	// done must be accessed atomically. A value greater than 0 indicates
	// that the read loop can exit.
	var done uint32
	doneCh := make(chan struct{})
	go func() {
		for sc.Scan() {
			t := sc.Text()
			if strings.Contains(t, want) {
				atomic.StoreUint32(&done, 1)
				close(doneCh)
				break
			}
			if atomic.LoadUint32(&done) > 0 {
				break
			}
		}
	}()
	select {
	case <-time.After(timeout):
		atomic.StoreUint32(&done, 1)
		return fmt.Errorf("timeout waiting to read %q", want)
	case <-doneCh:
		return nil
	}
}

`