File: custom_retryer.go

package info (click to toggle)
golang-github-aws-aws-sdk-go 1.49.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 312,636 kB
  • sloc: makefile: 120
file content (79 lines) | stat: -rw-r--r-- 2,621 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//go:build example
// +build example

package main

import (
	"fmt"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/aws/client"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/defaults"
	"github.com/aws/aws-sdk-go/aws/endpoints"
	"github.com/aws/aws-sdk-go/aws/request"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
)

func main() {
	sess := session.Must(
		session.NewSession(&aws.Config{
			// Use a custom retryer to provide custom retry rules.
			Retryer: CustomRetryer{
				DefaultRetryer: client.DefaultRetryer{
					NumMaxRetries: client.DefaultRetryerMaxNumRetries,
				}},

			// Use the SDK's SharedCredentialsProvider directly instead of the
			// SDK's default credential chain. This ensures that the
			// application can call Config.Credentials.Expire. This  is counter
			// to the SDK's default credentials chain, which  will never reread
			// the shared credentials file.
			Credentials: credentials.NewCredentials(&credentials.SharedCredentialsProvider{
				Filename: defaults.SharedCredentialsFilename(),
				Profile:  "default",
			}),
			Region: aws.String(endpoints.UsWest2RegionID),
		}),
	)
	// Add a request handler to the AfterRetry handler stack that is used by the
	// SDK to be executed after the SDK has determined if it will retry.
	// This handler forces the SDK's Credentials to be expired, and next call to
	// Credentials.Get will attempt to refresh the credentials.
	sess.Handlers.AfterRetry.PushBack(func(req *request.Request) {
		if aerr, ok := req.Error.(awserr.RequestFailure); ok && aerr != nil {
			if aerr.Code() == "InvalidClaimException" {
				// Force the credentials to expire based on error code.  Next
				// call to Credentials.Get will attempt to refresh credentials.
				req.Config.Credentials.Expire()
			}
		}
	})

	svc := cloudwatchlogs.New(sess)

	resp, err := svc.DescribeLogGroups(&cloudwatchlogs.DescribeLogGroupsInput{})

	fmt.Println(resp, err)
}

// CustomRetryer wraps the SDK's built in DefaultRetryer adding additional
// custom features. Such as, no retry for 5xx status codes, and refresh
// credentials.
type CustomRetryer struct {
	client.DefaultRetryer
}

// ShouldRetry overrides the SDK's built in DefaultRetryer adding customization
// to not retry 5xx status codes.
func (r CustomRetryer) ShouldRetry(req *request.Request) bool {
	if req.HTTPResponse.StatusCode >= 500 {
		// Don't retry any 5xx status codes.
		return false
	}

	// Fallback to SDK's built in retry rules
	return r.DefaultRetryer.ShouldRetry(req)
}