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