Closed3
Go Concurrency Patterns
Summary
In just a few simple transformations we used Go's concurrency primitives to convert a
slow
- sequential
- failure-sensitive
- program into one that is
fast
- concurrent
- replicated
- robust.
p.50: Google Search 3.0 complete program
var (
Web1 = fakeSearch("web")
Web2 = fakeSearch("web")
Image1 = fakeSearch("image")
Image2 = fakeSearch("image")
Video1 = fakeSearch("video")
Video2 = fakeSearch("video")
)
// This generate Search type function based on searchType
func fakeSearch(searchType string) Search {
return func(query string) Result { return Result{} }
}
// Function type contruct
type Search func(query string) Result
// Anything should be fine
type Result struct{}
// Run search concurrently on multiple replicas
// the fastest one is used, and others are discarded
func First(query string, replicas ...Search) Result {
c := make(chan Result)
searchReplica := func(i int) { c <- replicas[i](query) }
for i := range replicas {
go searchReplica(i)
}
return <-c
}
// Assuming in part of layered arch
type SearchUseCase struct {
results []Result
}
// The main logic performs operation
func (su *SearchUseCase) Query(query string) {
c := make(chan Result)
timeout := time.After(3 * time.Second)
go func() { c <- First(query, Web1, Web2) }()
go func() { c <- First(query, Image1, Image2) }()
go func() { c <- First(query, Video1, Video2) }()
for i := 0; i < 3; i++ {
select {
case result := <-c:
su.results = append(su.results, result)
case <-timeout:
fmt.Println("timeout")
return
}
}
}
このスクラップは2023/11/15にクローズされました