4 回答
TA貢獻1841條經驗 獲得超3個贊
我進行更簡單的重試。
使用更簡單的循環邏輯來確保正確性。
我們在執行重試之前會睡覺,因此請用作睡眠的條件。
i > 0
代碼如下:
func retry(attempts int, sleep time.Duration, f func() error) (err error) {
for i := 0; i < attempts; i++ {
if i > 0 {
log.Println("retrying after error:", err)
time.Sleep(sleep)
sleep *= 2
}
err = f()
if err == nil {
return nil
}
}
return fmt.Errorf("after %d attempts, last error: %s", attempts, err)
}
TA貢獻1816條經驗 獲得超6個贊
我知道這是一個古老的問題,但在搜索重試時遇到了它,并將其用作解決方案的基礎。
此版本可以接受具有 2 個返回值的函數,并在 golang 1.18 中使用泛型來實現這一點。我在1.17中嘗試過,但無法找到使該方法通用的方法。
這可以擴展到任何類型的任意數量的返回值。我在這里使用過,但可以限制為類型列表。any
func retry[T any](attempts int, sleep int, f func() (T, error)) (result T, err error) {
for i := 0; i < attempts; i++ {
if i > 0 {
log.Println("retrying after error:", err)
time.Sleep(time.Duration(sleep) * time.Second)
sleep *= 2
}
result, err = f()
if err == nil {
return result, nil
}
}
return result, fmt.Errorf("after %d attempts, last error: %s", attempts, err)
}
用法示例:
var config Configuration
something, err := retry(config.RetryAttempts, config.RetrySleep, func() (Something, error) { return GetSomething(config.Parameter) })
func GetSomething(parameter string) (something Something, err error) {
// Do something flakey here that might need a retry...
return something, error
}
希望這能幫助與我具有相同用例的人。
TA貢獻1155條經驗 獲得超0個贊
在GoPlayground中接受的答案的評論中,我會考慮添加一些東西。在 for 循環中使用 continue 和 break 會使循環更加簡單,因為不使用該語句。此外,我會在所有函數中使用早期返回來直接返回錯誤。最后,我會一直使用錯誤來檢查函數是否失敗,檢查值的有效性應該在執行的函數本身內部。if i > 0 {
這將是我的小嘗試:
package main
import (
"errors"
"fmt"
"log"
"time"
)
func main() {
var complicatedFunctionPassing bool = false
var attempts int = 5
// if complicatedFunctionPassing is true retry just makes one try
// if complicatedFunctionPassing is false retry makes ... attempts
err := retry(attempts, time.Second, func() (err error) {
if !complicatedFunctionPassing {
return errors.New("somthing went wrong in the important function")
}
log.Println("Complicated function passed")
return nil
})
if err != nil {
log.Printf("failed after %d attempts with error: %s", attempts, err.Error())
}
}
func retry(attempts int, sleep time.Duration, f func() error) (err error) {
for i := 0; i < attempts; i++ {
fmt.Println("This is attempt number", i+1)
// calling the important function
err = f()
if err != nil {
log.Printf("error occured after attempt number %d: %s", i+1, err.Error())
log.Println("sleeping for: ", sleep.String())
time.Sleep(sleep)
sleep *= 2
continue
}
break
}
return err
}
你可以在這里嘗試一下:https://go.dev/play/p/Ag8ObCb980U
- 4 回答
- 0 關注
- 170 瀏覽
添加回答
舉報
