Skip to content

Commit 120d3a6

Browse files
authored
Merge pull request #104 from deploymenttheory/dev
Added ping functionality
2 parents c348b1f + a31120f commit 120d3a6

File tree

2 files changed

+81
-1
lines changed

2 files changed

+81
-1
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2021 Sebastian Gräf
3+
Copyright (c) 2024 Deployment Theory
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

httpclient/httpclient_ping.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// httpclient_ping.go
2+
package httpclient
3+
4+
import (
5+
"fmt"
6+
"net/http"
7+
"time"
8+
9+
"go.uber.org/zap"
10+
)
11+
12+
// DoPing performs an HTTP "ping" to the specified endpoint using the given HTTP method, body,
13+
// and output variable. It attempts the request until a 200 OK response is received or the
14+
// maximum number of retry attempts is reached. The function uses a backoff strategy for retries
15+
// to manage load on the server and network. This function is useful for checking the availability
16+
// or health of an endpoint, particularly in environments where network reliability might be an issue.
17+
18+
// Parameters:
19+
// - method: The HTTP method to be used for the request. This should typically be "GET" for a ping operation, but the function is designed to accommodate any HTTP method.
20+
// - endpoint: The target API endpoint for the ping request. This should be a relative path that will be appended to the base URL configured for the HTTP client.
21+
// - body: The payload for the request, if any. For a typical ping operation, this would be nil, but the function is designed to accommodate requests that might require a body.
22+
// - out: A pointer to an output variable where the response will be deserialized. This is included to maintain consistency with the signature of other request functions, but for a ping operation, it might not be used.
23+
24+
// Returns:
25+
// - *http.Response: The HTTP response from the server. In case of a successful ping (200 OK),
26+
// this response contains the status code, headers, and body of the response. In case of errors
27+
// or if the maximum number of retries is reached without a successful response, this will be the
28+
// last received HTTP response.
29+
//
30+
// - error: An error object indicating failure during the execution of the ping operation. This
31+
// could be due to network issues, server errors, or reaching the maximum number of retry attempts
32+
// without receiving a 200 OK response.
33+
34+
// Usage:
35+
// This function is intended for use in scenarios where it's necessary to confirm the availability
36+
// or health of an endpoint, with built-in retry logic to handle transient network or server issues.
37+
// The caller is responsible for handling the response and error according to their needs, including
38+
// closing the response body when applicable to avoid resource leaks.
39+
40+
// Example:
41+
// var result MyResponseType
42+
// resp, err := client.DoPing("GET", "/api/health", nil, &result)
43+
//
44+
// if err != nil {
45+
// // Handle error
46+
// }
47+
//
48+
// // Process response
49+
func (c *Client) DoPing(method, endpoint string, body, out interface{}) (*http.Response, error) {
50+
log := c.Logger
51+
log.Debug("Starting Ping", zap.String("method", method), zap.String("endpoint", endpoint))
52+
53+
// Initialize retry count and define maximum retries
54+
var retryCount int
55+
maxRetries := c.clientConfig.ClientOptions.MaxRetryAttempts
56+
57+
// Loop until a successful response is received or maximum retries are reached
58+
for retryCount <= maxRetries {
59+
// Use the existing 'do' function for sending the request
60+
resp, err := c.executeRequest(method, endpoint, body, out)
61+
62+
// If request is successful and returns 200 status code, return the response
63+
if err == nil && resp.StatusCode == http.StatusOK {
64+
log.Debug("Ping successful", zap.String("method", method), zap.String("endpoint", endpoint))
65+
return resp, nil
66+
}
67+
68+
// Increment retry count and log the attempt
69+
retryCount++
70+
log.Warn("Ping failed, retrying...", zap.String("method", method), zap.String("endpoint", endpoint), zap.Int("retryCount", retryCount))
71+
72+
// Calculate backoff duration and wait before retrying
73+
backoffDuration := calculateBackoff(retryCount)
74+
time.Sleep(backoffDuration)
75+
}
76+
77+
// If maximum retries are reached without a successful response, return an error
78+
log.Error("Ping failed after maximum retries", zap.String("method", method), zap.String("endpoint", endpoint))
79+
return nil, fmt.Errorf("ping failed after %d retries", maxRetries)
80+
}

0 commit comments

Comments
 (0)