-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathretryable.go
43 lines (35 loc) · 1.1 KB
/
retryable.go
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
/*
Copyright © 2024 Acronis International GmbH.
Released under MIT license.
*/
package dbkit
import (
"database/sql/driver"
"reflect"
"github.com/acronis/go-appkit/retry"
)
var retryableErrors = map[reflect.Type]retry.IsRetryable{}
// GetIsRetryable returns a function that can tell for given driver if error is retryable.
func GetIsRetryable(d driver.Driver) retry.IsRetryable {
t := reflect.TypeOf(d)
if r, ok := retryableErrors[t]; ok {
return r
}
return isRetryableNoDriver
}
func isRetryableNoDriver(error) bool {
return false
}
// RegisterIsRetryableFunc registers callback to determinate specific DB error is retryable or not.
// Several registered functions will be called one after another in FIFO order before some function returns true.
// Note: this function is not concurrent-safe. Typical scenario: register all custom IsRetryable in module init()
func RegisterIsRetryableFunc(d driver.Driver, retryable retry.IsRetryable) {
t := reflect.TypeOf(d)
prev, ok := retryableErrors[t]
retryableErrors[t] = func(e error) bool {
if ok && prev(e) {
return true
}
return retryable(e)
}
}