0

I'm using such a select on multiple cases:

for {
    select {
    case data:= <- highFreqChan:
        // do something:
    case <- time.After(time.Second * 5):
        // send some heartbeat like data...
    }
}

I find that, if highFreqChan got huge data, the heartbeat case will not enter, and when stop sending data to highFreqChan, the heartbeat case alive again, how to make it always enter the heartbeat case while the highFreqChan still working?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
coanor
  • 3,746
  • 4
  • 50
  • 67
  • 1
    You can add the heartbeat to separate goroutine – bayrinat Dec 25 '17 at 09:30
  • Possible duplicate of [Writing Sleep function based on time.After](https://stackoverflow.com/questions/32937883/writing-sleep-function-based-on-time-after/32937957#32937957). – icza Dec 25 '17 at 12:29

1 Answers1

7

You're running time.After as part of the select condition, which means it's evaluated at the time the select is reached... which means that it will expire 5 seconds after the select is reached. So you will only enter that case if highFreqChan doesn't have any data for 5 seconds straight.

If you want to do something every 5 seconds, use a time.Ticker instead, like so:

heartbeat := time.NewTicker(5 * time.Second)
defer heartbeat.Stop()
for {
    select {
    case data:= <- highFreqChan:
        // do something:
    case <- heartbeat.C:
        // send some heartbeat like data...
    }
}
hobbs
  • 223,387
  • 19
  • 210
  • 288