Description
The mirror() function in nats.go can panic with "send on closed channel" when the consumer closes mch while messages are still being received on nch.
Stack trace
panic: send on closed channel
goroutine 5677 [running]:
github.com/mikluko/peanats.(*connectionImpl).mirror.func1()
github.com/mikluko/peanats@v0.20.2/nats.go:199 +0x4c
created by github.com/mikluko/peanats.(*connectionImpl).mirror in goroutine 5831
github.com/mikluko/peanats@v0.20.2/nats.go:197 +0x80
Root cause
https://github.com/mikluko/peanats/blob/main/nats.go#L196-L203
func (c *connectionImpl) mirror(mch chan Msg) chan *nats.Msg {
nch := make(chan *nats.Msg, cap(mch))
go func() {
for msg := range nch {
mch <- NewMsg(msg) // panics if mch is closed
}
}()
return nch
}
The goroutine doesn't handle the case where mch is closed by the consumer.
Suggested fix
Use a done channel or recover:
func (c *connectionImpl) mirror(mch chan Msg) chan *nats.Msg {
nch := make(chan *nats.Msg, cap(mch))
go func() {
defer func() {
recover() // ignore send on closed channel
}()
for msg := range nch {
mch <- NewMsg(msg)
}
}()
return nch
}
Or better, use select with a done channel to allow graceful shutdown.
Version
v0.20.2
Description
The
mirror()function innats.gocan panic with "send on closed channel" when the consumer closesmchwhile messages are still being received onnch.Stack trace
Root cause
https://github.com/mikluko/peanats/blob/main/nats.go#L196-L203
The goroutine doesn't handle the case where
mchis closed by the consumer.Suggested fix
Use a done channel or recover:
Or better, use select with a done channel to allow graceful shutdown.
Version
v0.20.2