go - 将重试策略变成可重用的函数

标签 go retrypolicy

我们的项目有一个简单的重试策略:

  1. 在第一个错误上, sleep 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
}

有没有办法把上面的代码变成可重用的函数?

最佳答案

只需将 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
}

关于go - 将重试策略变成可重用的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55825685/

相关文章:

go - 如何制作接受字符串参数的函数,并根据它返回不同的结构类型?

c# - Microsoft.Azure.ServiceBus - SubscriptionClient 忽略 RetryPolicy (RetryExponencial)

amazon-web-services - 在 AWS CDK 中设置状态机时,如何删除 Lambda 调用的默认重试策略?

azure - 逻辑应用程序是否支持具有随机增量的指数回退

java - 如何在 Spring 中将 Retryable 和 CircuitBreaker 结合在一起?

html - golang 中是否有 boilerpipe?

javascript - 如何呈现带有链接但没有其他 html 的用户帖子?

arrays - 将字节数组转换为 float64

amazon-web-services - 无法将 dynamodb 结果解码为具有定义为类型接口(interface)的字段的结构

c# - Azure Function 上的 FixDelayRetry 属性无法正常工作