Hello!
Today I demonstrating concurrency design pattern FANin.
In this sample concurrency design pattern FANin is being demonstrated using GoRoutine, Channels, Range, Select
Imp points
- Range will keep iterating and fetching the value until channel will be closed
- Select is useful which we are dealing with multiple channels together and we need to fetch from the channel whichever is ready with value.
In this design pattern a single channel accepts inputs from multiple output channels.
package main
import "fmt"
func main() {
even := make(chan int)
odd := make(chan int)
fanin := make(chan int)
// Send, this will alunch a go routine, which will execute saparatly from mai routine
go sendChannel(even, odd)
go receiveChannel(even, odd, fanin)
// range on channel will iterate until channel will be closed
for v := range fanin {
fmt.Printf("FanIn Channel value %v \n", v)
}
fmt.Printf("About to Exit")
}
func sendChannel(e, o chan<- int) {
defer close(e)
defer close(o)
for index := 0; index < 10; index++ {
if index%2 == 0 {
e <- index
} else {
o <- index
}
}
}
func receiveChannel(e, o <-chan int, f int) {
var okay int
for {
select {
case v, ok := <-e: // v will capture the channel value and ok will capture the state of channel
if !ok { // If channel is closed then increase okay
fmt.Printf("Even channel closed: %v \n", ok)
okay++
} else {
fmt.Printf("Even channel Value received: %v \n", v)
f <- v // Assign the value to fanin channel
}
case v, ok := <-o:
if !ok {
fmt.Printf("Odd channel closed: %v \n", ok)
okay++
} else {
fmt.Printf("Odd channel Value received: %v \n", v)
f <- v
}
}
// Loop exit condition
if okay == 2 {
fmt.Printf("Loop ends: %v \n", okay)
close(f)
return
}
}
}
Cheers
Dev