package main import ( "context" "fmt" "log" "net/http" "time" ) // simulateExternalAPICall simulates a call to an external API func simulateExternalAPICall(ctx context.Context) (string, error) { // Simulate varying response times delay := 3 * time.Second // For demonstration, let's make some calls intentionally slow if ctx.Value("callID").(int)%2 == 0 { delay = 6 * time.Second // Every other call is slow } select { case <-time.After(delay): return fmt.Sprintf("Data from external API (delay %v)", delay), nil case <-ctx.Done(): return "", ctx.Err() // Context was canceled or timed out } } func main() { fmt.Println("Starting external API call timeout example...") for i := 1; i <= 5; i++ { // Create a context with a timeout for each call ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) ctx = context.WithValue(ctx, "callID", i) // Add a call ID for logging defer cancel() // Ensure resources are cleaned up fmt.Printf(" Attempting API call %d with 5s timeout... ", i) result, err := simulateExternalAPICall(ctx) if err != nil { if err == context.DeadlineExceeded { fmt.Printf("API Call %d timed out: %v ", i, err) } else { fmt.Printf("API Call %d failed: %v ", i, err) } } else { fmt.Printf("API Call %d succeeded: %s ", i, result) } } // Example with an HTTP request client timeout fmt.Println(" --- HTTP Client Timeout Example ---") client := &http.Client{ Timeout: 2 * time.Second, // Global timeout for client requests } req, err := http.NewRequest("GET", "https://httpbin.org/delay/3", nil) // This will intentionally delay for 3s if err != nil { log.Fatal(err) } fmt.Println("Making HTTP GET request to httpbin.org/delay/3 with client timeout 2s...") resp, err := client.Do(req) if err != nil { fmt.Printf("HTTP Request failed: %v ", err) } else { defer resp.Body.Close() fmt.Printf("HTTP Request succeeded (Status: %s) ", resp.Status) } }