title: Could someone explain this block of Go code that uses channels? I don't understand how it's doing 500 actions at a time
body: <p>I was looking up knowledge on how to perform a lot of HTTP requests efficiently, and I came across this answer: <a href="https://stackoverflow.com/a/23319730/749851">https://stackoverflow.com/a/23319730/749851</a> with this code:</p>
  
  <pre><code>package main
  
  import (
      "flag"
      "fmt"
      "log"
      "net/http"
      "runtime"
      "time"
  )
  
  var (
      reqs int
      max  int
  )
  
  func init() {
      flag.IntVar(&amp;reqs, "reqs", 1000000, "Total requests")
      flag.IntVar(&amp;max, "concurrent", 200, "Maximum concurrent requests")
  }
  
  type Response struct {
      *http.Response
      err error
  }
  
  // Dispatcher
  func dispatcher(reqChan chan *http.Request) {
      defer close(reqChan)
      for i := 0; i &lt; reqs; i++ {
          req, err := http.NewRequest("GET", "http://localhost/", nil)
          if err != nil {
              log.Println(err)
          }
          reqChan &lt;- req
      }
  }
  
  // Worker Pool
  func workerPool(reqChan chan *http.Request, respChan chan Response) {
      t := &amp;http.Transport{}
      for i := 0; i &lt; max; i++ {
          go worker(t, reqChan, respChan)
      }
  }
  
  // Worker
  func worker(t *http.Transport, reqChan chan *http.Request, respChan chan Response) {
      for req := range reqChan {
          resp, err := t.RoundTrip(req)
          r := Response{resp, err}
          respChan &lt;- r
      }
  }
  
  // Consumer
  func consumer(respChan chan Response) (int64, int64) {
      var (
          conns int64
          size  int64
      )
      for conns &lt; int64(reqs) {
          select {
          case r, ok := &lt;-respChan:
              if ok {
                  if r.err != nil {
                      log.Println(r.err)
                  } else {
                      size += r.ContentLength
                      if err := r.Body.Close(); err != nil {
                          log.Println(r.err)
                      }
                  }
                  conns++
              }
          }
      }
      return conns, size
  }
  
  func main() {
      flag.Parse()
      runtime.GOMAXPROCS(runtime.NumCPU())
      reqChan := make(chan *http.Request)
      respChan := make(chan Response)
      start := time.Now()
      go dispatcher(reqChan)
      go workerPool(reqChan, respChan)
      conns, size := consumer(respChan)
      took := time.Since(start)
      ns := took.Nanoseconds()
      av := ns / conns
      average, err := time.ParseDuration(fmt.Sprintf("%d", av) + "ns")
      if err != nil {
          log.Println(err)
      }
      fmt.Printf("Connections:\t%d\nConcurrent:\t%d\nTotal size:\t%d bytes\nTotal time:\t%s\nAverage time:\t%s\n", conns, max, size, took, average)
  }
  </code></pre>
  
  <p>I'm coming from node so I don't really understand this "go" code.</p>
  
  <p>What part of it is limiting it to 500 HTTP actions at a time? And is it operating in chunks of 500, waiting until that chunk of 500 is finished then starting a new 500, OR is it just always chugging along adding 1 more once it hits 499, etc.</p>
  
  <p>I see that the "workerPool" func goes over a loop only as many times as the maximum amount of concurrent requests, calling "worker" 500 times, but how does it do the next 500 or even the whole 1 million eventually?</p>