@@ -6,6 +6,7 @@ For additional details please refer to: https://github.com/Clever/leakybucket/tr
6
6
package dynamodb
7
7
8
8
import (
9
+ "strings"
9
10
"sync"
10
11
"time"
11
12
@@ -14,6 +15,7 @@ import (
14
15
"github.com/aws/aws-sdk-go/aws"
15
16
"github.com/aws/aws-sdk-go/aws/session"
16
17
"github.com/aws/aws-sdk-go/service/dynamodb"
18
+ "github.com/eapache/go-resiliency/retrier"
17
19
)
18
20
19
21
var _ leakybucket.Bucket = & bucket {}
@@ -132,10 +134,16 @@ func New(tableName string, s *session.Session, itemTTL time.Duration) (*Storage,
132
134
ttl : itemTTL ,
133
135
}
134
136
135
- // fail early if the table doesn't exist or we have any other issues with the DynamoDB API
136
- if _ , err := ddb .DescribeTable (& dynamodb.DescribeTableInput {
137
- TableName : aws .String (tableName ),
138
- }); err != nil {
137
+ // Fail early if the table doesn't exist or we have any other issues with the DynamoDB API
138
+ // but guarantee we retry dial timeouts to be tolerant to a networking blip
139
+ r := retrier .New (retrier .ExponentialBackoff (5 , 1 * time .Second ), dialTimeoutRetrier {})
140
+ err := r .Run (func () error {
141
+ _ , err := ddb .DescribeTable (& dynamodb.DescribeTableInput {
142
+ TableName : aws .String (tableName ),
143
+ })
144
+ return err
145
+ })
146
+ if err != nil {
139
147
return nil , err
140
148
}
141
149
@@ -157,3 +165,20 @@ func min(a, b uint) uint {
157
165
}
158
166
return b
159
167
}
168
+
169
+ // dialTimeoutRetrier classifies errors from DynamoDB API in the form of
170
+ // Post https://dynamodb.{region}.amazonaws.com: dial tcp x.x.x.x: i/o timeout
171
+ // as retryable errors. This classifier is only used in `New` as we don't want to override the
172
+ // consumer's configuration during normal operation
173
+ type dialTimeoutRetrier struct {}
174
+
175
+ var _ retrier.Classifier = dialTimeoutRetrier {}
176
+
177
+ func (dialTimeoutRetrier ) Classify (err error ) retrier.Action {
178
+ if err == nil {
179
+ return retrier .Succeed
180
+ } else if strings .Contains (err .Error (), "dial tcp" ) && strings .Contains (err .Error (), "i/o timeout" ) {
181
+ return retrier .Retry
182
+ }
183
+ return retrier .Fail
184
+ }
0 commit comments