Skip to content
This repository was archived by the owner on Jan 15, 2024. It is now read-only.

Commit e5fb6a3

Browse files
authored
Merge pull request #150 from grafana/inkel/fix-retry-missing-body
Fix retry mechanism not sending body if first request fails before reading the body
2 parents 3f84a92 + 09a55c8 commit e5fb6a3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+179
-131
lines changed

admin.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package gapi
22

33
import (
4-
"bytes"
54
"encoding/json"
65
"fmt"
76
)
@@ -25,7 +24,7 @@ func (c *Client) CreateUser(user User) (int64, error) {
2524
ID int64 `json:"id"`
2625
}{}
2726

28-
err = c.request("POST", "/api/admin/users", nil, bytes.NewBuffer(data), &created)
27+
err = c.request("POST", "/api/admin/users", nil, data, &created)
2928
if err != nil {
3029
return id, err
3130
}
@@ -45,7 +44,7 @@ func (c *Client) UpdateUserPassword(id int64, password string) error {
4544
if err != nil {
4645
return err
4746
}
48-
return c.request("PUT", fmt.Sprintf("/api/admin/users/%d/password", id), nil, bytes.NewBuffer(data), nil)
47+
return c.request("PUT", fmt.Sprintf("/api/admin/users/%d/password", id), nil, data, nil)
4948
}
5049

5150
// UpdateUserPermissions sets a user's admin status.
@@ -55,7 +54,7 @@ func (c *Client) UpdateUserPermissions(id int64, isAdmin bool) error {
5554
if err != nil {
5655
return err
5756
}
58-
return c.request("PUT", fmt.Sprintf("/api/admin/users/%d/permissions", id), nil, bytes.NewBuffer(data), nil)
57+
return c.request("PUT", fmt.Sprintf("/api/admin/users/%d/permissions", id), nil, data, nil)
5958
}
6059

6160
// PauseAllAlerts pauses all Grafana alerts.
@@ -68,7 +67,7 @@ func (c *Client) PauseAllAlerts() (PauseAllAlertsResponse, error) {
6867
return result, err
6968
}
7069

71-
err = c.request("POST", "/api/admin/pause-all-alerts", nil, bytes.NewBuffer(data), &result)
70+
err = c.request("POST", "/api/admin/pause-all-alerts", nil, data, &result)
7271

7372
return result, err
7473
}

alert.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package gapi
22

33
import (
4-
"bytes"
54
"encoding/json"
65
"fmt"
76
"net/url"
@@ -68,7 +67,7 @@ func (c *Client) PauseAlert(id int64) (PauseAlertResponse, error) {
6867
return result, err
6968
}
7069

71-
err = c.request("POST", path, nil, bytes.NewBuffer(data), &result)
70+
err = c.request("POST", path, nil, data, &result)
7271
if err != nil {
7372
return result, err
7473
}

alerting_alert_rule.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package gapi
22

33
import (
4-
"bytes"
54
"encoding/json"
65
"fmt"
76
"time"
@@ -93,7 +92,7 @@ func (c *Client) SetAlertRuleGroup(group RuleGroup) error {
9392
}
9493

9594
uri := fmt.Sprintf("/api/v1/provisioning/folder/%s/rule-groups/%s", folderUID, name)
96-
return c.request("PUT", uri, nil, bytes.NewBuffer(req), nil)
95+
return c.request("PUT", uri, nil, req, nil)
9796
}
9897

9998
// NewAlertRule creates a new alert rule and returns its UID.
@@ -104,7 +103,7 @@ func (c *Client) NewAlertRule(ar *AlertRule) (string, error) {
104103
return "", err
105104
}
106105
result := AlertRule{}
107-
err = c.request("POST", "/api/v1/provisioning/alert-rules", nil, bytes.NewBuffer(req), &result)
106+
err = c.request("POST", "/api/v1/provisioning/alert-rules", nil, req, &result)
108107
if err != nil {
109108
return "", err
110109
}
@@ -120,7 +119,7 @@ func (c *Client) UpdateAlertRule(ar *AlertRule) error {
120119
return err
121120
}
122121

123-
return c.request("PUT", uri, nil, bytes.NewBuffer(req), nil)
122+
return c.request("PUT", uri, nil, req, nil)
124123
}
125124

126125
// DeleteAlertRule deletes a alert rule, identified by the alert rule's UID.

alerting_contact_point.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package gapi
22

33
import (
4-
"bytes"
54
"encoding/json"
65
"fmt"
76
"net/url"
@@ -62,7 +61,7 @@ func (c *Client) NewContactPoint(p *ContactPoint) (string, error) {
6261
}
6362
result := ContactPoint{}
6463

65-
err = c.request("POST", "/api/v1/provisioning/contact-points", nil, bytes.NewBuffer(req), &result)
64+
err = c.request("POST", "/api/v1/provisioning/contact-points", nil, req, &result)
6665
if err != nil {
6766
return "", err
6867
}
@@ -77,7 +76,7 @@ func (c *Client) UpdateContactPoint(p *ContactPoint) error {
7776
return err
7877
}
7978

80-
return c.request("PUT", uri, nil, bytes.NewBuffer(req), nil)
79+
return c.request("PUT", uri, nil, req, nil)
8180
}
8281

8382
// DeleteContactPoint deletes a contact point.

alerting_message_template.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package gapi
22

33
import (
4-
"bytes"
54
"encoding/json"
65
"fmt"
76
)
@@ -44,7 +43,7 @@ func (c *Client) SetMessageTemplate(name, content string) error {
4443
}
4544

4645
uri := fmt.Sprintf("/api/v1/provisioning/templates/%s", name)
47-
return c.request("PUT", uri, nil, bytes.NewBuffer(body), nil)
46+
return c.request("PUT", uri, nil, body, nil)
4847
}
4948

5049
// DeleteMessageTemplate deletes a message template.

alerting_mute_timing.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package gapi
22

33
import (
4-
"bytes"
54
"encoding/json"
65
"fmt"
76
)
@@ -65,7 +64,7 @@ func (c *Client) NewMuteTiming(mt *MuteTiming) error {
6564
return err
6665
}
6766

68-
return c.request("POST", "/api/v1/provisioning/mute-timings", nil, bytes.NewBuffer(req), nil)
67+
return c.request("POST", "/api/v1/provisioning/mute-timings", nil, req, nil)
6968
}
7069

7170
// UpdateMuteTiming updates a mute timing.
@@ -76,7 +75,7 @@ func (c *Client) UpdateMuteTiming(mt *MuteTiming) error {
7675
return err
7776
}
7877

79-
return c.request("PUT", uri, nil, bytes.NewBuffer(req), nil)
78+
return c.request("PUT", uri, nil, req, nil)
8079
}
8180

8281
// DeleteMutetiming deletes a mute timing.

alerting_notification_policy.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package gapi
22

33
import (
4-
"bytes"
54
"encoding/json"
65
"fmt"
76
)
@@ -116,7 +115,7 @@ func (c *Client) SetNotificationPolicyTree(np *NotificationPolicyTree) error {
116115
if err != nil {
117116
return err
118117
}
119-
return c.request("PUT", "/api/v1/provisioning/policies", nil, bytes.NewBuffer(req), nil)
118+
return c.request("PUT", "/api/v1/provisioning/policies", nil, req, nil)
120119
}
121120

122121
func (c *Client) ResetNotificationPolicyTree() error {

alertnotification.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package gapi
22

33
import (
4-
"bytes"
54
"encoding/json"
65
"fmt"
76
)
@@ -59,7 +58,7 @@ func (c *Client) NewAlertNotification(a *AlertNotification) (int64, error) {
5958
ID int64 `json:"id"`
6059
}{}
6160

62-
err = c.request("POST", "/api/alert-notifications", nil, bytes.NewBuffer(data), &result)
61+
err = c.request("POST", "/api/alert-notifications", nil, data, &result)
6362
if err != nil {
6463
return 0, err
6564
}
@@ -75,7 +74,7 @@ func (c *Client) UpdateAlertNotification(a *AlertNotification) error {
7574
if err != nil {
7675
return err
7776
}
78-
err = c.request("PUT", path, nil, bytes.NewBuffer(data), nil)
77+
err = c.request("PUT", path, nil, data, nil)
7978

8079
return err
8180
}

annotation.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package gapi
22

33
import (
4-
"bytes"
54
"encoding/json"
65
"fmt"
76
"net/url"
@@ -58,7 +57,7 @@ func (c *Client) NewAnnotation(a *Annotation) (int64, error) {
5857
ID int64 `json:"id"`
5958
}{}
6059

61-
err = c.request("POST", "/api/annotations", nil, bytes.NewBuffer(data), &result)
60+
err = c.request("POST", "/api/annotations", nil, data, &result)
6261
if err != nil {
6362
return 0, err
6463
}
@@ -77,7 +76,7 @@ func (c *Client) NewGraphiteAnnotation(gfa *GraphiteAnnotation) (int64, error) {
7776
ID int64 `json:"id"`
7877
}{}
7978

80-
err = c.request("POST", "/api/annotations/graphite", nil, bytes.NewBuffer(data), &result)
79+
err = c.request("POST", "/api/annotations/graphite", nil, data, &result)
8180
if err != nil {
8281
return 0, err
8382
}
@@ -97,7 +96,7 @@ func (c *Client) UpdateAnnotation(id int64, a *Annotation) (string, error) {
9796
Message string `json:"message"`
9897
}{}
9998

100-
err = c.request("PUT", path, nil, bytes.NewBuffer(data), &result)
99+
err = c.request("PUT", path, nil, data, &result)
101100
if err != nil {
102101
return "", err
103102
}
@@ -117,7 +116,7 @@ func (c *Client) PatchAnnotation(id int64, a *Annotation) (string, error) {
117116
Message string `json:"message"`
118117
}{}
119118

120-
err = c.request("PATCH", path, nil, bytes.NewBuffer(data), &result)
119+
err = c.request("PATCH", path, nil, data, &result)
121120
if err != nil {
122121
return "", err
123122
}
@@ -132,7 +131,7 @@ func (c *Client) DeleteAnnotation(id int64) (string, error) {
132131
Message string `json:"message"`
133132
}{}
134133

135-
err := c.request("DELETE", path, nil, bytes.NewBuffer(nil), &result)
134+
err := c.request("DELETE", path, nil, nil, &result)
136135
if err != nil {
137136
return "", err
138137
}
@@ -147,7 +146,7 @@ func (c *Client) DeleteAnnotationByRegionID(id int64) (string, error) {
147146
Message string `json:"message"`
148147
}{}
149148

150-
err := c.request("DELETE", path, nil, bytes.NewBuffer(nil), &result)
149+
err := c.request("DELETE", path, nil, nil, &result)
151150
if err != nil {
152151
return "", err
153152
}

api_key.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package gapi
22

33
import (
4-
"bytes"
54
"encoding/json"
65
"fmt"
76
"net/url"
@@ -42,7 +41,7 @@ func (c *Client) CreateAPIKey(request CreateAPIKeyRequest) (CreateAPIKeyResponse
4241
return response, err
4342
}
4443

45-
err = c.request("POST", "/api/auth/keys", nil, bytes.NewBuffer(data), &response)
44+
err = c.request("POST", "/api/auth/keys", nil, data, &response)
4645
return response, err
4746
}
4847

builtin_role_assignments.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package gapi
22

33
import (
4-
"bytes"
54
"encoding/json"
65
"fmt"
76
)
@@ -33,7 +32,7 @@ func (c *Client) NewBuiltInRoleAssignment(builtInRoleAssignment BuiltInRoleAssig
3332

3433
br := &BuiltInRoleAssignment{}
3534

36-
err = c.request("POST", baseURL, nil, bytes.NewBuffer(body), &br)
35+
err = c.request("POST", baseURL, nil, body, &br)
3736
if err != nil {
3837
return nil, err
3938
}
@@ -52,7 +51,7 @@ func (c *Client) DeleteBuiltInRoleAssignment(builtInRole BuiltInRoleAssignment)
5251
"global": {fmt.Sprint(builtInRole.Global)},
5352
}
5453
url := fmt.Sprintf("%s/%s/roles/%s", baseURL, builtInRole.BuiltinRole, builtInRole.RoleUID)
55-
err = c.request("DELETE", url, qp, bytes.NewBuffer(data), nil)
54+
err = c.request("DELETE", url, qp, data, nil)
5655

5756
return err
5857
}

client.go

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ type Config struct {
4040
OrgID int64
4141
// NumRetries contains the number of attempted retries
4242
NumRetries int
43+
// RetryTimeout says how long to wait before retrying a request
44+
RetryTimeout time.Duration
4345
}
4446

4547
// New creates a new Grafana client.
@@ -71,35 +73,27 @@ func (c Client) WithOrgID(orgID int64) *Client {
7173
return &c
7274
}
7375

74-
func (c *Client) request(method, requestPath string, query url.Values, body io.Reader, responseStruct interface{}) error {
76+
func (c *Client) request(method, requestPath string, query url.Values, body []byte, responseStruct interface{}) error {
7577
var (
7678
req *http.Request
7779
resp *http.Response
7880
err error
7981
bodyContents []byte
8082
)
8183

82-
// If we want to retry a request that sends data, we'll need to stash the request data in memory. Otherwise, we lose it since readers cannot be replayed.
83-
var bodyBuffer bytes.Buffer
84-
if c.config.NumRetries > 0 && body != nil {
85-
body = io.TeeReader(body, &bodyBuffer)
86-
}
87-
8884
// retry logic
8985
for n := 0; n <= c.config.NumRetries; n++ {
90-
// If it's not the first request, re-use the request body we stashed earlier.
91-
if n > 0 {
92-
body = bytes.NewReader(bodyBuffer.Bytes())
93-
}
94-
95-
req, err = c.newRequest(method, requestPath, query, body)
86+
req, err = c.newRequest(method, requestPath, query, bytes.NewReader(body))
9687
if err != nil {
9788
return err
9889
}
9990

10091
// Wait a bit if that's not the first request
10192
if n != 0 {
102-
time.Sleep(time.Second * 5)
93+
if c.config.RetryTimeout == 0 {
94+
c.config.RetryTimeout = time.Second * 5
95+
}
96+
time.Sleep(c.config.RetryTimeout)
10397
}
10498

10599
resp, err = c.client.Do(req)

0 commit comments

Comments
 (0)