mirror of
https://github.com/crazybber/awesome-patterns.git
synced 2024-11-25 06:16:03 +03:00
added error handling channel
This commit is contained in:
parent
33a9afa2cc
commit
9a117d3f5c
87
concurrency/error_handle/main.go
Normal file
87
concurrency/error_handle/main.go
Normal file
@ -0,0 +1,87 @@
|
||||
package main
|
||||
|
||||
// n general, your concurrent processes should send their
|
||||
// errors to another part of your program that has complete information
|
||||
// about the state of your program, and can make a more informed decision about what to do.
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// noErrorHandling()
|
||||
errorHandling()
|
||||
}
|
||||
|
||||
// Here we create a type that encompasses both the *http.Response and the error
|
||||
// possible from an iteration of the loop within our goroutine.
|
||||
type Result struct {
|
||||
Error error
|
||||
Response *http.Response
|
||||
}
|
||||
|
||||
func errorHandling() {
|
||||
// This line returns a channel that can be read from to retrieve results of an iteration of our loop
|
||||
checkStatus := func(done <-chan interface{}, urls ...string) <-chan Result {
|
||||
results := make(chan Result)
|
||||
go func() {
|
||||
defer close(results)
|
||||
for _, url := range urls {
|
||||
var result Result
|
||||
resp, err := http.Get(url)
|
||||
// Here we create a Result instance with the Error and Response fields set.
|
||||
result = Result{Error: err, Response: resp}
|
||||
select {
|
||||
case <-done:
|
||||
return
|
||||
// This is where we write the Result to our channel
|
||||
case results <- result:
|
||||
}
|
||||
}
|
||||
}()
|
||||
return results
|
||||
}
|
||||
done := make(chan interface{})
|
||||
defer close(done)
|
||||
urls := []string{"https://www.google.com", "https://badhost"}
|
||||
for result := range checkStatus(done, urls...) {
|
||||
// Here, in our main goroutine, we are able to deal with errors coming out of the
|
||||
// goroutine started by checkStatus intelligently, and with the full context of the larger program.
|
||||
if result.Error != nil {
|
||||
fmt.Printf("error: %v", result.Error)
|
||||
continue
|
||||
}
|
||||
fmt.Printf("Response: %v\n", result.Response.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func noErrorHandling() {
|
||||
checkStatus := func(
|
||||
done <-chan interface{},
|
||||
urls ...string,
|
||||
) <-chan *http.Response {
|
||||
responses := make(chan *http.Response)
|
||||
go func() {
|
||||
defer close(responses)
|
||||
for _, url := range urls {
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
continue
|
||||
}
|
||||
select {
|
||||
case <-done:
|
||||
return
|
||||
case responses <- resp:
|
||||
}
|
||||
}
|
||||
}()
|
||||
return responses
|
||||
}
|
||||
done := make(chan interface{})
|
||||
defer close(done)
|
||||
urls := []string{"https://www.google.com", "https://badhost"}
|
||||
for response := range checkStatus(done, urls...) {
|
||||
fmt.Printf("Response: %v\n", response.Status)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user