/
timeoutClient.go
97 lines (86 loc) · 1.72 KB
/
timeoutClient.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package main
import (
"context"
"fmt"
"io"
"net/http"
"os"
"strconv"
"sync"
"time"
)
var myUrl string
var delay int = 5
var wg sync.WaitGroup
type myData struct {
r *http.Response
err error
}
// In packages that use contexts, convention is to pass them as
// the first argument to a function.
func connect(c context.Context) error {
defer wg.Done()
data := make(chan myData, 1)
tr := &http.Transport{}
httpClient := &http.Client{Transport: tr}
req, _ := http.NewRequest("GET", myUrl, nil)
go func() {
response, err := httpClient.Do(req)
if err != nil {
fmt.Println(err)
data <- myData{nil, err}
return
} else {
pack := myData{response, err}
data <- pack
}
}()
select {
case <-c.Done():
tr.CancelRequest(req)
<-data
fmt.Println("The request was canceled!")
return c.Err()
case ok := <-data:
err := ok.err
resp := ok.r
if err != nil {
fmt.Println("Error select:", err)
return err
}
defer resp.Body.Close()
realHTTPData, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error select:", err)
return err
}
// Although fmt.Printf() is used here, server processes
// use the log.Printf() function instead.
fmt.Printf("Server Response: %s\n", realHTTPData)
}
return nil
}
func main() {
if len(os.Args) == 1 {
fmt.Println("Need a URL and a delay!")
return
}
myUrl = os.Args[1]
if len(os.Args) == 3 {
t, err := strconv.Atoi(os.Args[2])
if err != nil {
fmt.Println(err)
return
}
delay = t
}
fmt.Println("Delay:", delay)
c := context.Background()
c, cancel := context.WithTimeout(c, time.Duration(delay)*time.Second)
defer cancel()
fmt.Printf("Connecting to %s \n", myUrl)
wg.Add(1)
go connect(c)
wg.Wait()
fmt.Println("Exiting...")
}