golang Try重试机制解读 | KaiQ.Gu|KerwinKoo Blog

JerryXia 发表于 , 阅读 (0)

golang-try

golang官方没有try关键字做代码尝试执行,但github中有人为其做了个try功能的语法糖。

try用法举例

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
package main

import (
"errors"
"fmt"
"github.com/matryer/try"
"math/rand"
"time"
)

func main() {
var value string

err := try.Do(func(attempt int) (bool, error) {
var err error
value, err = randomFunc()
if err != nil {
fmt.Println("run error:", err)
} else {
fmt.Println("run ok:", value)
}

return attempt < 5, err //设置尝试次数,即尝试5次
})

if err != nil {
fmt.Println("ERROR:", err)
}
}

func randomFunc() (string, error) {
rand_seed := rand.New(rand.NewSource(time.Now().UnixNano()))
if rand_seed.Intn(100) < 50 {
return "test ok", nil
} else {
return "", errors.New("test error")
}
}

代码解释:

  • try退出条件:1、达到尝试次数:5次(默认+最高尝试次数是10次)\;或者2、执行函数的返回值中error变量值为nil。

golang-try包源码解析

源码list

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
package try

import "errors"

// MaxRetries is the maximum number of retries before bailing.
var MaxRetries = 10

var errMaxRetriesReached = errors.New("exceeded retry limit")

// Func represents functions that can be retried.
type Func func(attempt int) (retry bool, err error)

// Do keeps trying the function until the second argument
// returns false, or no error is returned.
func Do(fn Func) error {
var err error
var cont bool
attempt := 1
for {
cont, err = fn(attempt)
if !cont || err == nil {
break
}
attempt++
if attempt > MaxRetries {
return errMaxRetriesReached
}
}
return err
}

// IsMaxRetries checks whether the error is due to hitting the
// maximum number of retries or not.
func IsMaxRetries(err error) bool {
return err == errMaxRetriesReached
}

源码解析

  • 从包源码结构中看,两个执行函数,DoIsMaxRetries

Do

Do的参数是类型为func(attempt int) (retry bool, err error)的函数指针,因此参数的定义格式必须满足Func自定义类的格式要求。该函数参数有两个返回值,retryerr,这两个返回值是try是否退出尝试的关键标准,if !cont || err == nil判定语句中标识,retry(即cont)为false或err没有报错时,函数退出。因此在使用try.Do时,必须指定这两个变量。

次数控制由Do中attempt变量决定。attempt每执行一次自动+1,并传入Func参数中,Func参数根据指定的循环try次数,决定retry返回值是否为true,当true时,则继续重试执行。