将重试策略转换为可重用功能

时间:2019-04-24 08:33:53

标签: go retrypolicy

对于我们的项目,我们有一个简单的重试政策:

  1. 在第一个错误上,睡眠1秒钟。
  2. 在第二个错误上,睡眠5秒钟。
  3. 第三个错误时,请睡眠10秒钟。
  4. 关于第四个错误,请退出重试并返回错误。

这是我们的重试政策:

package main

import (
    "errors"  
    "fmt"         
    "time"    
)

func main() {
    errorCount := 0
    var err error

    fmt.Println("start!")

    for {
        err = generateError()
        if err != nil {
            if errorCount == 0 {
                fmt.Println("sleeping for 1 second...")
                time.Sleep(1 * time.Second)    
            } else if errorCount == 1 {
                fmt.Println("sleeping for 5 seconds...")
                time.Sleep(5 * time.Second)    
            } else if errorCount == 2 {
                fmt.Println("sleeping for 10 seconds...")
                time.Sleep(10 * time.Second)    
            } else {
                fmt.Println("giving up...")
                break
            }

            errorCount++
        } else {
            fmt.Println("no errors!")
            break
        }
    }

    fmt.Println("error:", err)
    fmt.Println("done!")
}

func generateError() error {
    err := errors.New("something happened")
    return err
}

是否可以将上述代码转换为可重用的功能?

1 个答案:

答案 0 :(得分:4)

只需将generateError作为参数传递(我简化了重试功能,因为我无法自救):

package main

import (
    "errors"
    "fmt"
    "time"
)

func main() {
    retry(generateError)
}

func retry(f func() error) {
    fmt.Println("start!")

    backoff := []time.Duration{
        1 * time.Second,
        5 * time.Second,
        10 * time.Second,
    }

    var err error
    for _, d := range backoff {
        err = f()
        if err != nil {
            fmt.Printf("sleeping for %v...\n", d)
            time.Sleep(d)
        } else {
            fmt.Println("no errors!")
            return
        }
    }

    fmt.Println("error:", err)
    fmt.Println("done!")
}

func generateError() error {
    err := errors.New("something happened")
    return err
}