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
}
}