github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/blog/content/pipelines/sqbuffer.go (about)

     1  // +build OMIT
     2  
     3  package main
     4  
     5  import (
     6  	"fmt"
     7  	"sync"
     8  )
     9  
    10  // gen sends the values in nums on the returned channel, then closes it.
    11  func gen(nums ...int) <-chan int {
    12  	out := make(chan int, len(nums))
    13  	for _, n := range nums {
    14  		out <- n
    15  	}
    16  	close(out)
    17  	return out
    18  }
    19  
    20  // sq receives values from in, squares them, and sends them on the returned
    21  // channel, until in is closed.  Then sq closes the returned channel.
    22  func sq(in <-chan int) <-chan int {
    23  	out := make(chan int)
    24  	go func() {
    25  		for n := range in {
    26  			out <- n * n
    27  		}
    28  		close(out)
    29  	}()
    30  	return out
    31  }
    32  
    33  // merge receives values from each input channel and sends them on the returned
    34  // channel.  merge closes the returned channel after all the input values have
    35  // been sent.
    36  func merge(cs ...<-chan int) <-chan int {
    37  	var wg sync.WaitGroup
    38  	out := make(chan int, 1) // enough space for the unread inputs
    39  	// ... the rest is unchanged ...
    40  
    41  	// Start an output goroutine for each input channel in cs.  output
    42  	// copies values from c to out until c is closed, then calls wg.Done.
    43  	output := func(c <-chan int) {
    44  		for n := range c {
    45  			out <- n
    46  		}
    47  		wg.Done()
    48  	}
    49  	wg.Add(len(cs))
    50  	for _, c := range cs {
    51  		go output(c)
    52  	}
    53  
    54  	// Start a goroutine to close out once all the output goroutines are
    55  	// done.  This must start after the wg.Add call.
    56  	go func() {
    57  		wg.Wait()
    58  		close(out)
    59  	}()
    60  	return out
    61  }
    62  
    63  func main() {
    64  	in := gen(2, 3)
    65  
    66  	// Distribute the sq work across two goroutines that both read from in.
    67  	c1 := sq(in)
    68  	c2 := sq(in)
    69  
    70  	// Consume the first value from output.
    71  	out := merge(c1, c2)
    72  	fmt.Println(<-out) // 4 or 9
    73  	return
    74  	// The second value is sent into out's buffer, and all goroutines exit.
    75  }