Skip to content

Commit 6633f43

Browse files
committed
Support retry for Eventually consistency failure
1 parent 51e7bef commit 6633f43

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 4.43.0 (Unreleased)
2+
3+
### Added
4+
- Support change compartment using lifecycle state
5+
- Support retry for Eventually consistency failure
6+
17
## 4.42.0 (September 01, 2021)
28

39
### Added

oci/retry.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package oci
55

66
import (
7+
"fmt"
78
"log"
89
"math/rand"
910
"strings"
@@ -116,6 +117,11 @@ func getDefaultExpectedRetryDuration(response oci_common.OCIOperationResponse, d
116117
return defaultRetryTime
117118
}
118119

120+
if ok, remainingEc := isRetriableByEc(response); ok && remainingEc != nil {
121+
log.Printf("[DEBUG] Retrying Eventual consistency...")
122+
return *remainingEc
123+
}
124+
119125
if response.Response == nil || response.Response.HTTPResponse() == nil {
120126
return 0
121127
}
@@ -156,12 +162,54 @@ func getDefaultExpectedRetryDuration(response oci_common.OCIOperationResponse, d
156162
return defaultRetryTime
157163
}
158164

165+
func isRetriableByEc(r oci_common.OCIOperationResponse) (bool, *time.Duration) {
166+
if _, ok := oci_common.IsServiceError(r.Error); ok {
167+
now := time.Now()
168+
if r.EndOfWindowTime == nil || r.EndOfWindowTime.Before(now) {
169+
// either no eventually consistent effects, or they have disappeared by now
170+
Debugln(fmt.Sprintf("EC.ShouldRetryOperation, no EC or in the past, returning false: endOfWindowTime = %v, now = %v", r.EndOfWindowTime, now))
171+
return false, nil
172+
}
173+
// there were eventually consistent effects present at the time of the first request
174+
// and they could still affect the retries
175+
if oci_common.IsErrorAffectedByEventualConsistency(r.Error) {
176+
// and it's one of the three affected error codes
177+
Debugln(fmt.Sprintf("EC.ShouldRetryOperation, affected by EC, EC is present: endOfWindowTime = %v, now = %v", r.EndOfWindowTime, now))
178+
return true, getRemainingEventualConsistencyDuration(r)
179+
}
180+
return false, nil
181+
}
182+
return false, nil
183+
}
184+
185+
// returns the remaining time with eventual consistency, or nil if there is no eventual consistency
186+
func getRemainingEventualConsistencyDuration(r oci_common.OCIOperationResponse) *time.Duration {
187+
endOfWindow := oci_common.EcContext.GetEndOfWindow()
188+
if endOfWindow != nil {
189+
// there was an eventually consistent request
190+
if endOfWindow.After(r.InitialAttemptTime) {
191+
// and the eventually consistent effects may still be present
192+
remaining := endOfWindow.Sub(time.Now())
193+
if remaining > 0 {
194+
return &remaining
195+
}
196+
}
197+
}
198+
199+
return nil
200+
}
201+
159202
func getIdentityExpectedRetryDuration(response oci_common.OCIOperationResponse, disableNotFoundRetries bool, optionals ...interface{}) time.Duration {
160203
defaultRetryTime := getDefaultExpectedRetryDuration(response, disableNotFoundRetries)
161204
if oci_common.IsNetworkError(response.Error) {
162205
return defaultRetryTime
163206
}
164207

208+
if ok, remainingEc := isRetriableByEc(response); ok && remainingEc != nil {
209+
log.Printf("[DEBUG] Retrying Eventual consistency...")
210+
return *remainingEc
211+
}
212+
165213
if response.Response == nil || response.Response.HTTPResponse() == nil {
166214
return defaultRetryTime
167215
}
@@ -188,6 +236,11 @@ func getDatabaseExpectedRetryDuration(response oci_common.OCIOperationResponse,
188236
return defaultRetryTime
189237
}
190238

239+
if ok, remainingEc := isRetriableByEc(response); ok && remainingEc != nil {
240+
log.Printf("[DEBUG] Retrying Eventual consistency...")
241+
return *remainingEc
242+
}
243+
191244
if response.Response == nil || response.Response.HTTPResponse() == nil {
192245
return defaultRetryTime
193246
}
@@ -209,6 +262,12 @@ func getObjectstorageServiceExpectedRetryDuration(response oci_common.OCIOperati
209262
if oci_common.IsNetworkError(response.Error) {
210263
return defaultRetryTime
211264
}
265+
266+
if ok, remainingEc := isRetriableByEc(response); ok && remainingEc != nil {
267+
log.Printf("[DEBUG] Retrying Eventual consistency...")
268+
return *remainingEc
269+
}
270+
212271
if response.Response == nil || response.Response.HTTPResponse() == nil {
213272
return defaultRetryTime
214273
}

0 commit comments

Comments
 (0)