awesome-patterns/concurrency/iterator_error_handling/main.go

114 lines
2.0 KiB
Go
Raw Normal View History

package main
import (
2018-01-24 10:18:41 +03:00
"fmt"
2018-05-02 13:23:43 +03:00
"net/http"
"time"
"github.com/davecgh/go-spew/spew"
)
type FetchResult struct {
Domain string
StatusCode uint
Header string
}
func dummyFetchUrl(url string) *FetchResult {
time.Sleep(time.Second * 1)
return &FetchResult{
url,
200,
"Dummy Header",
}
}
2018-01-24 10:18:41 +03:00
func concurrentFetch(urls []string) <-chan *FetchResult {
rChan := make(chan *FetchResult, len(urls))
for _, url := range urls {
go func(url string) {
result := dummyFetchUrl(url)
rChan <- result
}(url)
}
return rChan
}
func main() {
2018-05-02 13:23:43 +03:00
v2()
return
2018-01-24 10:18:41 +03:00
// mock the urls
urls := []string{
"test1",
"test2",
"test3",
"test4",
"test5",
"test6",
}
// this is a prefered method
chanResults := concurrentFetch(urls)
for i := 0; i < len(urls); i++ {
select {
case c := <-chanResults:
spew.Dump(c)
}
}
// i := 0
// for v := range concurrentFetch(urls) {
// spew.Dump(i, v)
// i++
// if i == len(urls) {
// break
// }
// }
fmt.Println("All my things are done")
}
2018-05-02 13:23:43 +03:00
type Result struct {
Error error
Response *http.Response
}
func v2() {
checkStatus := func(done <-chan interface{}, urls ...string) <-chan Result {
results := make(chan Result)
go func() {
defer close(results)
for _, url := range urls {
select {
case <-done:
return
2018-05-02 13:42:40 +03:00
default:
println("EXECUTE : ", url)
resp, err := http.Get(url)
results <- Result{Error: err, Response: resp}
2018-05-02 13:23:43 +03:00
}
}
}()
return results
}
done := make(chan interface{})
2018-05-02 13:42:40 +03:00
defer close(done)
urls := []string{
"https://www.google.com",
"https://blog.golang.org/pipelines",
"https://github.com/jianhan",
"https://insights.stackoverflow.com/survey/2017",
"A",
"https://hackernoon.com/top-10-python-web-frameworks-to-learn-in-2018-b2ebab969d1a",
"B",
}
2018-05-02 13:23:43 +03:00
for result := range checkStatus(done, urls...) {
if result.Error != nil {
2018-05-02 13:42:40 +03:00
done <- true
2018-05-02 13:23:43 +03:00
fmt.Printf("error: %v\n", result.Error)
2018-05-02 13:42:40 +03:00
break
2018-05-02 13:23:43 +03:00
}
fmt.Printf("Response: %v\n", result.Response.Status)
}
2018-05-02 13:42:40 +03:00
fmt.Println("End")
2018-05-02 13:23:43 +03:00
}