Skip to content

Commit 41a93a4

Browse files
authored
example: Add Custom Retry strategy example. (aws#1731)
Adds and example for writing a custom retryer that will provide alternative rules for when a request is retried. In addition to showing how the credentials can be force expired based on rules in addition to the SDK's defaults.
1 parent c8a63b5 commit 41a93a4

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Using Custom Retry Strategies with the SDK
2+
3+
This example highlights how you can define a custom retry strategy for the SDK to use. The example wraps the SDK's DefaultRetryer with a set of custom rules to not retry HTTP 5xx status codes. In all other cases the custom retry strategy falls back the SDK's DefaultRetryer's functionality.
4+
5+
## Usage
6+
7+
This example will attempt to make an Amazon CloudWatch Logs PutLogEvents DescribeLogGroups API call. This example expects to retrieve credentials from the `~/.aws/credentials` file.
8+
9+
```sh
10+
go run ./custom_retryer.go
11+
```
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// +build example
2+
3+
package main
4+
5+
import (
6+
"fmt"
7+
8+
"github.com/aws/aws-sdk-go/aws"
9+
"github.com/aws/aws-sdk-go/aws/awserr"
10+
"github.com/aws/aws-sdk-go/aws/client"
11+
"github.com/aws/aws-sdk-go/aws/credentials"
12+
"github.com/aws/aws-sdk-go/aws/defaults"
13+
"github.com/aws/aws-sdk-go/aws/endpoints"
14+
"github.com/aws/aws-sdk-go/aws/request"
15+
"github.com/aws/aws-sdk-go/aws/session"
16+
"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
17+
)
18+
19+
func main() {
20+
sess := session.Must(
21+
session.NewSession(&aws.Config{
22+
// Use a custom retryer to provide custom retry rules.
23+
Retryer: CustomRetryer{DefaultRetryer: client.DefaultRetryer{NumMaxRetries: 3}},
24+
25+
// Use the SDK's SharedCredentialsProvider directly instead of the
26+
// SDK's default credential chain. This ensures that the
27+
// application can call Config.Credentials.Expire. This is counter
28+
// to the SDK's default credentials chain, which will never reread
29+
// the shared credentials file.
30+
Credentials: credentials.NewCredentials(&credentials.SharedCredentialsProvider{
31+
Filename: defaults.SharedCredentialsFilename(),
32+
Profile: "default",
33+
}),
34+
Region: aws.String(endpoints.UsWest2RegionID),
35+
}),
36+
)
37+
// Add a request handler to the AfterRetry handler stack that is used by the
38+
// SDK to be executed after the SDK has determined if it will retry.
39+
// This handler forces the SDK's Credentials to be expired, and next call to
40+
// Credentials.Get will attempt to refresh the credentials.
41+
sess.Handlers.AfterRetry.PushBack(func(req *request.Request) {
42+
if aerr, ok := req.Error.(awserr.RequestFailure); ok && aerr != nil {
43+
if aerr.Code() == "InvalidClaimException" {
44+
// Force the credentials to expire based on error code. Next
45+
// call to Credentials.Get will attempt to refresh credentials.
46+
req.Config.Credentials.Expire()
47+
}
48+
}
49+
})
50+
51+
svc := cloudwatchlogs.New(sess)
52+
53+
resp, err := svc.DescribeLogGroups(&cloudwatchlogs.DescribeLogGroupsInput{})
54+
55+
fmt.Println(resp, err)
56+
}
57+
58+
// CustomRetryer wraps the SDK's built in DefaultRetryer adding additional
59+
// custom features. Such as, no retry for 5xx status codes, and refresh
60+
// credentials.
61+
type CustomRetryer struct {
62+
client.DefaultRetryer
63+
}
64+
65+
// ShouldRetry overrides the SDK's built in DefaultRetryer adding customization
66+
// to not retry 5xx status codes.
67+
func (r CustomRetryer) ShouldRetry(req *request.Request) bool {
68+
if req.HTTPResponse.StatusCode >= 500 {
69+
// Don't retry any 5xx status codes.
70+
return false
71+
}
72+
73+
// Fallback to SDK's built in retry rules
74+
return r.DefaultRetryer.ShouldRetry(req)
75+
}

0 commit comments

Comments
 (0)