dpkt31779 2019-04-24 08:33
浏览 24
已采纳

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

We have a simple retry policy for our project:

  1. On the first error, sleep for 1 second.
  2. On the second error, sleep for 5 seconds.
  3. On the third error, sleep for 10 seconds.
  4. On the fourth error, quit retrying and return the error.

Here is what our retry policy looks like:

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
}

Is there a way to turn the above code into a reusable function?

  • 写回答

1条回答 默认 最新

  • douyu9433 2019-04-24 09:02
    关注

    Simply pass generateError as an argument (I simplified the retry function because I couldn't help myself):

    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...
    ", 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
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 基于单片机的靶位控制系统
  • ¥15 AT89C51控制8位八段数码管显示时钟。
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 下图接收小电路,谁知道原理
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错