Fan-Out / Fan-In Pattern
Fan-Out / Fan-In naqshi
Worker Pool'da bitta kanal (jobs) — ko'p worker orasida taqsimlanadi. "Fan-Out / Fan-In" naqshi shunga o'xshaydi, lekin bir oz kengroq: bir nechta bosqichni bir-biriga ulaydi, har bir bosqichda ishni "tarqatib" (fan-out), so'ng natijalarni "bitta joyga yig'ib" (fan-in) oladi.
Buni daryoning tarmoqlanishi va qayta qo'shilishiga o'xshating: bitta katta daryo bir nechta kichik irmoqqa bo'linadi (fan-out — ishni parallel bajarish uchun tarqatish), so'ng bu irmoqlar pastroqda yana bitta katta daryoga qo'shiladi (fan-in — natijalarni birlashtirish).
package main
import (
"fmt"
"sync"
)
func generator(nums ...int) <-chan int {
out := make(chan int)
go func() {
defer close(out)
for _, n := range nums {
out <- n
}
}()
return out
}
// fan-out: bitta kanaldan ikkita ishlov beruvchi yaratamiz
func square(in <-chan int) <-chan int {
out := make(chan int)
go func() {
defer close(out)
for n := range in {
out <- n * n
}
}()
return out
}
// fan-in: bir nechta kanalni bitta kanalga birlashtiramiz
func merge(channels ...<-chan int) <-chan int {
out := make(chan int)
var wg sync.WaitGroup
wg.Add(len(channels))
for _, c := range channels {
go func(c <-chan int) {
defer wg.Done()
for n := range c {
out <- n
}
}(c)
}
go func() {
wg.Wait()
close(out)
}()
return out
}
func main() {
in := generator(1, 2, 3, 4)
c1 := square(in)
c2 := square(in)
sum := 0
for n := range merge(c1, c2) {
sum += n
}
fmt.Println(sum)
}generator — bitta kanal orqali 1, 2, 3, 4 sonlarini "chiqarib beradi". Keyin biz shu bitta in kanalidan ikkita square ishlovchisini (c1, c2) yaratamiz — ikkalasi ham bir xil indan o'qiydi, shuning uchun sonlar ular orasida avtomatik taqsimlanadi (fan-out). Nihoyat, merge ikkala natija kanalini (c1, c2) bitta kanalga birlashtiradi (fan-in) — har bir kirish kanali uchun alohida goroutine ochib, hammasini bitta outga yozadi.
merge ichidagi sync.WaitGroup muhim: u "barcha kirish kanallari tugagach, outni yopish kerak" degan signalni to'g'ri boshqaradi. Agar buni unutsak, outni o'qiyotgan range sikli abadiy kutib qolardi ("Channel Directions" darsida ko'rgan yopilmagan kanal muammosi).
>_ Exercise
Uchinchi ishlov beruvchini (fan-out'ni kengaytirib) qo'shing.
- •generator(1, 2, 3, 4, 5, 6) chaqiring
- •shu bitta kanaldan UCHTA square ishlovchisini yarating (c1, c2, c3)
- •merge(c1, c2, c3) orqali birlashtirib, yig'indisini chop eting
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
Fan-Out — bitta manbadan bir nechta ishlovchini oziqlantirish, Fan-In — bir nechta natijani bitta oqimga birlashtirish; ikkalasi birga ishlatilib, ishni parallel bajarish quvurini (pipeline) tashkil qiladi.
NEXT UP
Circuit Breaker Pattern
$ go run main.go
Kodingizni ishga tushiring