文章目录
项目中常有发送短信
、发送邮件
、站内信
等应用。由网络、处理超时等引发发送失败,常规的做法是让它重试几次 :
代码实现
// 短信
type Sms struct {
Title /*标题*/, From /*发送者*/, To /*接收者*/, Content /*消息内容*/ string
}
// 模拟发短信
func (p *Sms) Send() error {
if (time.Now().Second())%5 == 0 {
log.Printf("【%s】向【%s】发送了一条短信:「%s」%s\n", p.From, p.To, p.Title, p.Content)
return nil
}
return errors.New("( ¯▽¯;) 网络异常( ¯▽¯;) ")
}
// 发送短信(失败重试)
// count: 尝试发送次数
// interval: 第一次失败重试间隔时间(后续间隔翻倍)
func (p *Sms) SendWithRetry(count uint8, interval time.Duration) {
if err := p.Send(); err != nil {
log.Println(err.Error())
if count--; count > 0 {
log.Printf("短信发送失败,%s后再次重试 #%d. \n", interval, count)
<-time.After(interval)
p.SendWithRetry(count, interval*2)
}
}
}
func TestRetry(t *testing.T) {
sms := &Sms{Title: "今晚吃鸡", From: "Lucy", To: "Lily", Content: "八点半开黑"}
sms.SendWithRetry(5, time.Second*2)
}
带有取消的重试
// 自定义Stop错误
type Stop struct {
error
}
func NewStop(msg string) Stop {
return Stop{errors.New(msg)}
}
// 短信
type Sms struct {
Title /*标题*/, From /*发送者*/, To /*接收者*/, Content /*消息内容*/ string
}
// 模拟发短信
func (p *Sms) Send() error {
if (time.Now().Second())%7 == 0 {
log.Printf("【%s】向【%s】发送了一条短信:「%s」%s\n", p.From, p.To, p.Title, p.Content)
return nil
}
//
if (time.Now().Second())%9 == 0 {
return NewStop("已取消重试")
}
return errors.New("( ¯▽¯;) 网络异常( ¯▽¯;) ")
}
// 发送短信(失败重试)
// count: 尝试发送次数
// interval: 第一次失败重试间隔时间(后续间隔翻倍)
func (p *Sms) SendWithRetry(count uint8, interval time.Duration) {
if err := p.Send(); err != nil {
if stop, ok := err.(Stop); ok {
log.Println(stop.Error())
return
}
log.Println(err.Error())
if count--; count > 0 {
log.Printf("短信发送失败,%s后再次重试 #%d. \n", interval, count)
<-time.After(interval)
p.SendWithRetry(count, interval)
}
}
}
func TestRetry(t *testing.T) {
sms := &Sms{Title: "今晚吃鸡", From: "Lucy", To: "Lily", Content: "八点半开黑"}
sms.SendWithRetry(5, time.Second*2)
}
引用:
https://github.com/mnhkahn/gogogo/blob/master/util/retry_util.go