-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1. generator 2. fan-in 3. fan-out
- Loading branch information
Showing
13 changed files
with
287 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Generator | ||
|
||
|
||
通常可以拿來做 pipeline 使用,避免一次讀取太大量資料。 其他使用方式還有類似 graceful shutdown 的方法。 | ||
|
||
參考 [Generator Pattern](./main.go) | ||
|
||
補充: 通常產生 channel 人最好要負責關閉 channel,原因有以下兩點 | ||
|
||
1. 無法向已 closed channel 寫入資料 | ||
2. 可以讀取已 closed channel 的資料 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package main | ||
|
||
import "fmt" | ||
|
||
func generateData() <-chan int { | ||
data := make(chan int, 1) | ||
|
||
go func(data chan int) { | ||
for i := 0; i < 10; i++ { | ||
data <- i | ||
} | ||
|
||
close(data) | ||
}(data) | ||
|
||
return data | ||
} | ||
|
||
func main() { | ||
data := generateData() | ||
|
||
for d := range data { | ||
fmt.Println(d) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Fan-in | ||
|
||
|
||
通常可以拿來做一些限制流量或是想從多個 output 統一收集 input 使用。 | ||
|
||
參考 [Fan-In Pattern](./main.go) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"sync" | ||
) | ||
|
||
func generateData() <-chan int { | ||
data := make(chan int, 1) | ||
|
||
go func(data chan int) { | ||
for i := 0; i < 10; i++ { | ||
data <- i | ||
} | ||
|
||
close(data) | ||
}(data) | ||
|
||
return data | ||
} | ||
|
||
func fanIn(sources ...<-chan int) <-chan int { | ||
target := make(chan int, 1) | ||
|
||
go func() { | ||
defer close(target) | ||
|
||
wg := sync.WaitGroup{} | ||
|
||
for _, source := range sources { | ||
wg.Add(1) | ||
go func(source <-chan int, target chan int) { | ||
defer wg.Done() | ||
for val := range source { | ||
target <- val | ||
} | ||
}(source, target) | ||
} | ||
|
||
wg.Wait() | ||
|
||
}() | ||
|
||
return target | ||
} | ||
|
||
func main() { | ||
data1 := generateData() | ||
data2 := generateData() | ||
target := fanIn(data1, data2) | ||
|
||
for d := range target { | ||
fmt.Println(d) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Fan-out | ||
|
||
通常可以拿來當做 Message Queue 使用,從單一 input 散佈到各個地方去。 | ||
|
||
參考 [Fan-Out Pattern](./main.go) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"time" | ||
) | ||
|
||
func generateData() <-chan int { | ||
data := make(chan int, 1) | ||
|
||
go func(data chan int) { | ||
for i := 0; i < 10; i++ { | ||
data <- i | ||
} | ||
|
||
close(data) | ||
}(data) | ||
|
||
return data | ||
} | ||
|
||
func fanOut(data <-chan int) <-chan int { | ||
target := make(chan int, 1) | ||
|
||
go func(data <-chan int) { | ||
defer close(target) | ||
for val := range data { | ||
target <- val | ||
} | ||
}(data) | ||
|
||
return target | ||
} | ||
|
||
func main() { | ||
data := generateData() | ||
target1 := fanOut(data) | ||
target2 := fanOut(data) | ||
|
||
go func() { | ||
for d := range target1 { | ||
fmt.Printf("target1: %d\n", d) | ||
} | ||
}() | ||
|
||
go func() { | ||
for d := range target2 { | ||
fmt.Printf("target2: %d\n", d) | ||
} | ||
}() | ||
|
||
time.Sleep(1 * time.Second) // Easily use time.Sleep to wait them finished instead of sync.WaitGroup | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Fan-In and Fan-Out | ||
|
||
把以上兩種做一個整合範例,雖然這範例看起來跟直接讀兩個 channel 很像,但實際上同個 target1 channel 是有可能拿到同樣的值的。 | ||
|
||
參考 [Fan-In and Fan-Out Pattern](./main.go) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"sync" | ||
"time" | ||
) | ||
|
||
func generateData() <-chan int { | ||
data := make(chan int, 1) | ||
|
||
go func(data chan int) { | ||
for i := 0; i < 10; i++ { | ||
data <- i | ||
} | ||
|
||
close(data) | ||
}(data) | ||
|
||
return data | ||
} | ||
|
||
func fanIn(sources ...<-chan int) <-chan int { | ||
target := make(chan int, 1) | ||
|
||
go func() { | ||
defer close(target) | ||
|
||
wg := sync.WaitGroup{} | ||
|
||
for _, source := range sources { | ||
wg.Add(1) | ||
go func(source <-chan int, target chan int) { | ||
defer wg.Done() | ||
for val := range source { | ||
target <- val | ||
} | ||
}(source, target) | ||
} | ||
|
||
wg.Wait() | ||
|
||
}() | ||
|
||
return target | ||
} | ||
|
||
func fanOut(data <-chan int) <-chan int { | ||
target := make(chan int, 1) | ||
|
||
go func(data <-chan int) { | ||
defer close(target) | ||
for val := range data { | ||
target <- val | ||
} | ||
}(data) | ||
|
||
return target | ||
} | ||
|
||
func main() { | ||
data1 := generateData() | ||
data2 := generateData() | ||
|
||
target := fanIn(data1, data2) | ||
|
||
target1 := fanOut(target) | ||
target2 := fanOut(target) | ||
|
||
go func() { | ||
for d := range target1 { | ||
fmt.Printf("target1: %d\n", d) | ||
} | ||
}() | ||
|
||
go func() { | ||
for d := range target2 { | ||
fmt.Printf("target2: %d\n", d) | ||
} | ||
}() | ||
|
||
time.Sleep(1 * time.Second) // Easily use time.Sleep to wait them finished instead of sync.WaitGroup | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# 介紹 | ||
|
||
此專案是 go concurrency patterns 的各式範例 | ||
|
||
# 大綱 | ||
|
||
|
||
| Number | Name | | ||
|--------|-------------------------------------------| | ||
| 1 | [Generator](./01-generator) | | ||
| 2 | [Fan-In](./02-fan-in) | | ||
| 3 | [Fan-Out](./03-fan-out) | | ||
| 4 | [Fan-In and Fan-Out](./04-fan-in-fan-out) | |