How does the program execute Poller function infinitely when the "in" channel in poller function(that receives from main function) run only 3 poller go routines ?
So, first the program creates two Pollers:
for i := 0; i < numPollers; i++ {
go Poller(pending, complete, status)
}
then it sends three resources to pending:
for _, url := range urls {
pending <- &Resource{url: url}
}
Every Poller reads from pending and polls the resource:
for r := range in {
s := r.Poll()
status <- State{r.url, s}
out <- r
}
This code seems to be executed infinitely, but it is blocking read from a queue, generally. So this loops wait for the next value to appear.
Let's virtually step over it:
- There is two Pollers reading resources.
- Program sends first resource to the queue.
- One of the pollers gets the resource and start to pool. Another one waits.
- At some moment the program sends new resource to the queue.
- As the first poller is busy, the second one gets unblocked and start polling.
- Program sends third resource and blocks as two pollers are busy.
- When one of the pollers completes, it takes the last resource and continues.
- At the meantime, the main program reads values from the complete queue.
for r := range in { s := r.Poll() status <- State{r.url, s} out <- r }
How does this code run infinitely? If it loops over "in" channel, and "in" gets its resources from pending queue, it should terminate after few iterations. I think this is exactly the part that I don't understand.
To be precise, in
does not gets the resources from pending
queue. in
is pending
queue. The queue (or channel, which I use interchangeably) can be closed by calling close but until it is not closed explicitly it is considered alive. Any reading from it blocks the current goroutine until the next value will be given. Then gorotine resumes.
I suppose that you keep thinking about channels like they are array with fixed number of elements. They are not. Consider they like array with infinite number of elements but with blocking read that may throw exception (that the rough approximation of closing the queue if you are not familiar with the concept).