gopl.io/ch5/wait/wait.go

51 lines
1.1 KiB
Go

// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
// See page 130.
// The wait program waits for an HTTP server to start responding.
package main
import (
"fmt"
"log"
"net/http"
"os"
"time"
)
//!+
// WaitForServer attempts to contact the server of a URL.
// It tries for one minute using exponential back-off.
// It reports an error if all attempts fail.
func WaitForServer(url string) error {
const timeout = 1 * time.Minute
deadline := time.Now().Add(timeout)
for tries := 0; time.Now().Before(deadline); tries++ {
_, err := http.Head(url)
if err == nil {
return nil // success
}
log.Printf("server not responding (%s); retrying...", err)
time.Sleep(time.Second << uint(tries)) // exponential back-off
}
return fmt.Errorf("server %s failed to respond after %s", url, timeout)
}
//!-
func main() {
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, "usage: wait url\n")
os.Exit(1)
}
url := os.Args[1]
//!+main
// (In function main.)
if err := WaitForServer(url); err != nil {
fmt.Fprintf(os.Stderr, "Site is down: %v\n", err)
os.Exit(1)
}
//!-main
}