I'm curious about the behaviour of channels and how they work in relation to loops. Suppose I have the following code:
Consumer
tick := time.Tick(time.Duration(2) * time.Second)
for {
select {
case <-tick:
p.channel <-true
}
}
And I have a goroutine that has the following:
Processor
for {
select {
case canProcess := <-p.channel:
// synchronous process that takes longer than 2 seconds
case <-p.stop:
return
}
}
What happens when the Consumer pushes to the channel faster than the Processor can complete its synchronous process?
Do they pile up waiting for the Processor to complete or do they skip a "beat" as such?
If they pile up, is there potential for memory leaking?
I know I can put the synchronous process in a goroutine instead, but this is really to understand how channels behave. (i.e. my example has a 2-second tick, but it doesn't have to).
select will only invoke next time.Tick if previous case corresponding code was completed,
you can still have some lever by specifying size of channel i.e channel := make(chan bool,10)
See below:
func main() {
channel := make(chan bool, 10)
go func() {
tick := time.Tick(time.Duration(1) * time.Second)
for {
select {
case <-tick:
fmt.Printf("Producer: TICK %v\n", time.Now())
channel <- true
}
}
}()
for {
select {
case canProcess := <-channel:
time.Sleep(3* time.Second)
fmt.Printf("Consumer: Completed : %v\n")
fmt.Printf("%v\n", canProcess)
}
}
}