| 398 | } |
| 399 | |
| 400 | func forNetwork(ctx context.Context, protocol string, address string, condition string, timeout time.Duration, waitInterval time.Duration) error { |
| 401 | l := logger.From(ctx) |
| 402 | timeoutCtx, cancel := context.WithTimeout(ctx, timeout) |
| 403 | defer cancel() |
| 404 | |
| 405 | condition = strings.ToLower(condition) |
| 406 | if condition == "" { |
| 407 | condition = "success" |
| 408 | } |
| 409 | |
| 410 | // Create an HTTP client with a per-request timeout that is slightly shorter than our wait-interval to prevent |
| 411 | // hanging on slow or unresponsive servers. |
| 412 | httpClient := &http.Client{ |
| 413 | Timeout: waitInterval - (time.Millisecond * 5), |
| 414 | } |
| 415 | |
| 416 | delay := 100 * time.Millisecond |
| 417 | |
| 418 | for { |
| 419 | // Delay the check for 100ms the first time and then the wait interval after that |
| 420 | pauseTimer := time.NewTimer(delay) |
| 421 | select { |
| 422 | case <-timeoutCtx.Done(): |
| 423 | pauseTimer.Stop() |
| 424 | if ctx.Err() != nil { |
| 425 | return fmt.Errorf("wait cancelled: %w", ctx.Err()) |
| 426 | } |
| 427 | return errors.New("wait timed out") |
| 428 | case <-pauseTimer.C: |
| 429 | } |
| 430 | delay = waitInterval |
| 431 | |
| 432 | switch protocol { |
| 433 | case "http", "https": |
| 434 | // Handle HTTP and HTTPS endpoints. |
| 435 | url := fmt.Sprintf("%s://%s", protocol, address) |
| 436 | req, err := http.NewRequestWithContext(timeoutCtx, http.MethodGet, url, nil) |
| 437 | if err != nil { |
| 438 | l.Debug(err.Error()) |
| 439 | continue |
| 440 | } |
| 441 | // Default to checking for a 2xx response. |
| 442 | if condition == "success" { |
| 443 | // Try to get the URL and check the status code. |
| 444 | resp, err := httpClient.Do(req) |
| 445 | if err != nil { |
| 446 | l.Debug(err.Error()) |
| 447 | continue |
| 448 | } |
| 449 | err = resp.Body.Close() |
| 450 | if err != nil { |
| 451 | l.Debug(err.Error()) |
| 452 | } |
| 453 | |
| 454 | // If the status code is not in the 2xx range, try again. |
| 455 | if resp.StatusCode < 200 || resp.StatusCode > 299 { |
| 456 | l.Debug("did not receive 2xx status code", "responseCode", resp.StatusCode) |
| 457 | continue |