Unexpected select behavior

I have some code that looks like the following
.
.
.
for {
select {
case sumData := <-incomingChannel:
doSomeWork(sumData)
case <-beatingHeart.C:
doHeartBeatStuff()
case <-ctx.Done():
return
}
}

The beatingHeart ticker is set for 2 seconds. The code works as expected as long as there is traffic on the incomingChannel. If the system is idle for a few hours, the ticker can be seen to not go off for 15-90 seconds, then return to its expected every 2 seconds.

When we use this same select pattern for several goroutines, nearly all of them exhibit this behavior at approximately the same time (within a second of each other).

Any thoughts?

I don’t get it. why the ticker go off?

Either the ticker does not go off every two seconds, or select is not picking it up. I don’t know which or how to tell. Has anyone seen this behavior before?

I haven’t seen this behavior before. Though in most cases where I’m spinning up goroutines to do things in the background like health checks / send queued emails / whatever I honestly probably wouldn’t notice if there was a 15-90 second delay intermittently. It’s interesting that all of the goroutines experience this same pattern at nearly the same time. Makes me wonder if there’s something going on at a higher level on your server. Like for example, is it possible that you are running this as a service, something panics and goes horribly awry, and the service restarts itself?

If I were you, I’d create a demo app to reproduce what you are seeing and create a ticket on the official go repo.