112 lines
2.1 KiB
Go
112 lines
2.1 KiB
Go
|
|
package ensureSendUtil
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"fmt"
|
|||
|
|
"time"
|
|||
|
|
|
|||
|
|
"goutil/debugUtil"
|
|||
|
|
"goutil/logUtil"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// 负责发送数据的协程
|
|||
|
|
func sendLoop(s sender, closeSignal chan struct{}) {
|
|||
|
|
defer func() {
|
|||
|
|
if r := recover(); r != nil {
|
|||
|
|
logUtil.LogUnknownError(r)
|
|||
|
|
}
|
|||
|
|
}()
|
|||
|
|
|
|||
|
|
for {
|
|||
|
|
select {
|
|||
|
|
case <-s.Done():
|
|||
|
|
closeSignal <- struct{}{}
|
|||
|
|
return
|
|||
|
|
case v := <-s.Data():
|
|||
|
|
if err := s.Send(v); err != nil {
|
|||
|
|
// 发送失败存入缓存
|
|||
|
|
s.Cache() <- v
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 定时重发失败的数据
|
|||
|
|
func resendLoop(s sender, folder string, closeSignal chan struct{}) {
|
|||
|
|
defer func() {
|
|||
|
|
if r := recover(); r != nil {
|
|||
|
|
logUtil.LogUnknownError(r)
|
|||
|
|
}
|
|||
|
|
}()
|
|||
|
|
|
|||
|
|
// debug模式每秒重试1次
|
|||
|
|
var delay time.Duration
|
|||
|
|
if debugUtil.IsDebug() {
|
|||
|
|
delay = time.Second
|
|||
|
|
} else {
|
|||
|
|
delay = time.Minute * 5
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 定时重发失败数据
|
|||
|
|
for {
|
|||
|
|
select {
|
|||
|
|
case <-s.Done():
|
|||
|
|
closeSignal <- struct{}{}
|
|||
|
|
return
|
|||
|
|
case <-time.After(delay):
|
|||
|
|
sendCacheData(s, folder)
|
|||
|
|
loadData(s.(EnsureSender), folder)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 从sender获取失败数据重发
|
|||
|
|
func sendCacheData(s sender, folder string) {
|
|||
|
|
failed := make([]dataItem, 0)
|
|||
|
|
length := len(s.Cache())
|
|||
|
|
|
|||
|
|
defer func() {
|
|||
|
|
// 用于记录多次失败后放弃发送的数据
|
|||
|
|
giveUpItems := make(chan dataItem, len(failed))
|
|||
|
|
|
|||
|
|
for _, v := range failed {
|
|||
|
|
if v.Count() >= 3 {
|
|||
|
|
// 失败次数太多的数据准备存放到磁盘中
|
|||
|
|
giveUpItems <- v
|
|||
|
|
} else {
|
|||
|
|
s.Cache() <- v
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
giveUpLen := len(giveUpItems)
|
|||
|
|
if giveUpLen > 0 {
|
|||
|
|
// 将多次失败的数据保存到文件中
|
|||
|
|
if folder[len(folder)-1] == '/' {
|
|||
|
|
folder = folder[:len(folder)-1]
|
|||
|
|
}
|
|||
|
|
saveData(giveUpItems, folder+"_giveup")
|
|||
|
|
|
|||
|
|
if giveUpLen >= 5 {
|
|||
|
|
log := fmt.Sprintf("ensureSendUtil: 有%d条数据多次发送失败", giveUpLen)
|
|||
|
|
logUtil.NormalLog(log, logUtil.Error)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 输出信息
|
|||
|
|
log := fmt.Sprintf("ensureSendUtil: 重发%d条数据,失败%d条,存盘%d条\n", length, len(failed), giveUpLen)
|
|||
|
|
logUtil.NormalLog(log, logUtil.Info)
|
|||
|
|
}()
|
|||
|
|
|
|||
|
|
for {
|
|||
|
|
select {
|
|||
|
|
case v := <-s.Cache():
|
|||
|
|
// 重发数据
|
|||
|
|
if e := s.Send(v); e != nil {
|
|||
|
|
// 记录失败的数据
|
|||
|
|
failed = append(failed, v)
|
|||
|
|
}
|
|||
|
|
default:
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|