title: Go routine ending mysteriously, channel closed without reaching close statement
body: <p>I created the following simple program to test the fan-in-fan-out pattern using channel. What it does is generate a few go routines to calculate the square of a number coming from an input channel and send the square into an output channel. All output channels will then be merged into a single channel to print the square in <code>main</code>.</p>
  <pre><code>func calculateSquare(in &lt;-chan int) &lt;-chan int {
      out := make(chan int)
  
      go func() {
         for num := range in {
             fmt.Printf(&quot;Receving num %v\n&quot;, num)
             out &lt;- num * num
             fmt.Printf(&quot;Sending square %v\n&quot;, num * num)
         }
         fmt.Println(&quot;Closing out&quot;)
         close(out)
      }()
  
      return out
  }
  
  func fanOut(in &lt;-chan int, workerCount int) []&lt;-chan int {
      outs := make([]&lt;-chan int, 0, workerCount)
  
      for i := 0 ; i &lt; workerCount ; i++ {
          outs = append(outs, calculateSquare(in))
      }
  
      return outs
  }
  
  func fanIn(outs []&lt;-chan int) &lt;-chan int {
      var wg sync.WaitGroup
  
      merge := make(chan int)
  
      for _, out := range outs {
          wg.Add(1)
  
          go func() {
              for result := range out {
                  merge &lt;- result
              }
  
              wg.Done()
          }()
      }
  
      go func() {
          wg.Wait()
          fmt.Println(&quot;Closing merge&quot;)
          close(merge)
      }()
  
      return merge
  }
  
  func main() {
      in := make(chan int)
  
      go func() {
          for i := 0 ; i &lt; 4 ; i++ {
              fmt.Printf(&quot;Sending num %v\n&quot;, i)
              in &lt;- i
          }
          close(in)
      }()
  
      outs := fanOut(in, 5)
      merge := fanIn(outs)
  
      for num := range merge {
          fmt.Printf(&quot;Final square %v\n&quot;, num)
      }
  }
  </code></pre>
  <p>In the <code>main</code> function, I'm sending in 4 numbers 0 -&gt; 3 into the input channel and I expect to see 4 square printed in the console. However, when I ran the program, even though the output fluctuates a bit but I never ever see 4 square numbers printed in the console.</p>
  <p>Below is a sample output I'm seeing.</p>
  <pre><code>Sending num 0
  Sending num 1
  Sending num 2
  Sending num 3
  Closing out
  Receving num 0
  Receving num 1
  Receving num 2
  Sending square  4
  Closing out
  Receving num 3
  Final square 4
  Closing merge
  </code></pre>
  <p>I'd be very grateful if someone could explain to me why <code>Receving num 1</code> was printed but <code>Sending square 1</code> is never coming. In addition, if <code>Sending square 1</code> is not printed, how did the <code>output</code> channel get closed. I'm only seeing 2 <code>Closing out</code>, yet, the wait group where I was merging the result ended its <code>Wait()</code>.</p>
  <p>I must have done something wrong somewhere.</p>