nats.go
nats.go copied to clipboard
timer.go.I'm wondering if it's an nats issue.
go 1.17.5, 1.17.6 . nats.go github.com/nats-io/nats.go v1.13.1-0.20211018182449-f2416a8b1483
some time the time.Timer returned by globalTimerPool.Get(a Duration) was fired already so request() will fail with "nats timeout" in 10us or less.
the issue disappears if I disable pool.
@sgof1d Would you have a test case that reproduce this? The pool implementation does the right thing, I believe, in that when putting it back to the pool it stops the timer and if it can't (meaning it had fired), then it consumes from the channel:
func (tp *timerPool) Put(t *time.Timer) {
if !t.Stop() {
select {
case <-t.C:
default:
}
}
tp.p.Put(t)
}
yes, It seems that pool does thing right. reproduce rate is about 10%. if I enable pool. reproduce rae is 0%, if I disable pool. the test case is : clients send websocket packet to api gateway gateway call nats.request() in go routines. backend server will response to these requests.
the issue happens in gateway.
I had tested that: if affirm timer.C is REALLY empty before Get() return, the issue disappear.
so I'm wondering something is wrong in timer.Stop(), the go standard lib.
I think I have seen some issue reports around that. Will try to reproduce with using simple timer/pool but outside of NATS and see... out of curiosity, which platform are you running on?
Probably related to https://github.com/golang/go/issues/47859?
I think I have seen some issue reports around that. Will try to reproduce with using simple timer/pool but outside of NATS and see... out of curiosity, which platform are you running on?
alpine running in container. macosx 12.1
Closing since looks like regression from Go that has been fixed since Go 1.16.