02/03/2020 - GO
İstemci uygulamanız bir sunucu uygulamasını çağırıyorsa, yanıtın mümkün olduğunca hızlı geri gelmesini istersiniz. Ancak, işlem yavaşsa işlemi iptal edebilirsiniz. Bu gibi durumlar için context WithTimeout veya WithCancel özelliğini kullanabilirsiniz.
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"time"
)
func main() {
handler := http.NewServeMux()
handler.HandleFunc("/client/api/v1/users", controller)
log.Fatal(http.ListenAndServe(":8080", handler))
}
func controller(w http.ResponseWriter, _ *http.Request) {
res, err := users()
if err != nil {
_, _ = w.Write([]byte(err.Error()))
return
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
_, _ = w.Write([]byte(err.Error()))
return
}
res.Body.Close()
_, _ = w.Write(body)
}
// See users() function below for examples.
Her ne kadar bu yazı context hakkında olsada, tüm iptal işlemini aşağıda gösterildiği gibi http.Client.Timeout
parametresini kullanarakta yapabilirsiniz.
func users() (*http.Response, error) {
req, err := http.NewRequest(http.MethodGet, "http://localhost:8090/server/api/v1/users", nil)
if err != nil {
return nil, err
}
client := http.Client{Timeout: 1 * time.Second}
res, err := client.Do(req)
if err != nil {
fmt.Printf("%t\n", err)
fmt.Printf("%T\n", err)
return nil, err
}
return res, nil
}
İstemci zaman aşımı oluşursa hata bir * url.Error
örneği olur ve içerik aşağıdakine benzer.
&{
%!t(string=Get)
%!t(string=http://localhost:8090/server/api/v1/users)
%!t(*http.httpError=&{
net/http: request canceled (Client.Timeout exceeded while awaiting headers)
true
}
)
}
func users() (*http.Response, error) {
req, err := http.NewRequest(http.MethodGet, "http://localhost:8090/server/api/v1/users", nil)
if err != nil {
return nil, err
}
ctx, cancel := context.WithTimeout(context.Background(), 1 * time.Second)
defer cancel()
client := http.Client{}
res, err := client.Do(req.WithContext(ctx))
if err != nil {
fmt.Printf("%t\n", err)
fmt.Printf("%T\n", err)
return nil, err
}
return res, nil
}
İstemci isteğinin contexinde zaman aşımı oluşursa hata bir *url.Error
örneği olur ve içerik aşağıdakine benzer.
&{
%!t(string=Get)
%!t(string=http://localhost:8090/server/api/v1/users)
{}
}
func users() (*http.Response, error) {
req, err := http.NewRequest(http.MethodGet, "http://localhost:8090/server/api/v1/users", nil)
if err != nil {
return nil, err
}
ctx, cancel := context.WithCancel(context.Background())
_ = time.AfterFunc(1 * time.Second, func() { cancel() })
client := http.Client{}
res, err := client.Do(req.WithContext(ctx))
if err != nil {
fmt.Printf("%t\n", err)
fmt.Printf("%T\n", err)
return nil, err
}
return res, nil
}
İstemci isteğinin contexinde iptal işlemi oluşursa hata bir *url.Error
örneği olur ve içerik aşağıdakine benzer.
&{
%!t(string=Get)
%!t(string=http://localhost:8090/server/api/v1/users)
%!t(*errors.errorString=&{
context canceled
}
)
}