有大佬可以帮忙看看 SendToProc 这个函数里 select+slice 会 panic 吗?感谢感谢🙏
func init() {
Chan = make(chan *GenData, 500000)
}
var Chan chan *GenData
type SendQueue struct {
queue []*GenData
size int
}
type GenData struct {
s string
}
func SendToProc() error {
go func() {
batchSize := 100
tc := time.NewTicker(time.Millisecond * 100)
sq := &SendQueue{
queue: make([]*GenData, 0),
size: 0,
}
for {
select {
case g := <-Chan:
sq.queue = append(sq.queue, g)
sq.size++
if sq.size == batchSize {
send(sq.queue)
sq.queue = sq.queue[:0]
sq.size = 0
}
case <-tc.C:
if sq.size > 0 {
send(sq.queue)
sq.queue = sq.queue[:0]
sq.size = 0
}
}
}
}()
return nil
}
func send(sendList []*GenData) {
for i, v := range sendList {
fmt.Println(i, v)
}
}
1
iyear 2023-06-20 22:14:02 +08:00
不太知道你觉得 panic 的点在哪里
|
3
iyear 2023-06-20 22:21:15 +08:00
浅看了一下,没有可能造成越界的代码,所以越界肯定不会。不过这个 size ,用 len 代替不好么,同时维护一致性上容易疏忽。
|
5
chenxiankong 2023-06-20 22:37:31 +08:00
没看出 panic 点,要不把 panic 报错和具体代码行发一下?
|
6
AnroZ 2023-06-20 22:41:44 +08:00 1
建议:
1. 增加下 goroutine 循环退出的响应 2. 习惯性的在这种 goroutine 函数增加一个 defer 函数 处理下异常 3. len 替换 size 4. 收不到 g chan 100 毫秒后再触发超时是不是更合理些,没必要周期性定时 100 毫秒 |
7
folivora OP @chenxiankong #5 主要是进程挂了,怀疑这个地方有问题 panic 了,想请诸位大佬人眼 debug 下。
|
9
folivora OP @iyear #8 是的,ticker 主要是控制了发送策略,达到 batchSize 或者每隔 0.1s 发送一次。
|
10
MoYi123 2023-06-21 10:28:13 +08:00
虽然是一样的, sq.size == batchSize 还是写 sq.size >= batchSize 看着安心一点.
|
11
pkoukk 2023-06-21 14:45:52 +08:00
6# 比较完整了。
一般我们会在 SendQueue 里加一个 context ,select 的时候加一项 ctx.Done()当做退出信号,清空队列里的数据,防止主进程退出时,队列里有东西没被处理掉。 |