Robię narzędzie do pobierania adresów URL w Go i mam listę adresów URL do pobrania. Wysyłam http.Get()
zapytania na każdy adres URL i otrzymuję odpowiedź.
resp,fetch_err := http.Get(url)
Jak mogę ustawić niestandardowy limit czasu dla każdego żądania Get? (Domyślny czas jest bardzo długi, co powoduje, że mój moduł pobierania jest naprawdę wolny). Chcę, aby mój moduł pobierania miał limit czasu wynoszący około 40-45 sekund, po którym powinien zwrócić komunikat „przekroczono limit czasu żądania” i przejść do następnego adresu URL.
Jak mogę to osiągnąć?
Odpowiedzi:
Najwyraźniej w Go 1.3 http Klient ma pole Timeout
To mi wystarczyło.
źródło
Get
zwraca błąd? Jestem trochę zdezorientowany, ponieważ Godoc forClient
mówi: Licznik czasu pozostaje uruchomiony po powrocie Get, Head, Post lub Do i przerwie czytanie Response.Body. Więc to znaczy, że alboGet
czy odczytResponse.Body
mógł być przerwany błędem?http.Client.Timeout
vs.http.Transport.ResponseHeaderTimeout
?http.Client.Timeout
obejmuje czas potrzebny na przeczytanie treści odpowiedzi,http.Transport.ResponseHeaderTimeout
nie zawiera jej.Musisz skonfigurować własnego klienta z własnym transportem, który wykorzystuje niestandardową funkcję wybierania, która otacza DialTimeout .
Coś takiego (całkowicie niesprawdzone ) to :
źródło
Aby dodać do odpowiedzi Volkera, jeśli chcesz również ustawić limit czasu odczytu / zapisu oprócz limitu czasu połączenia, możesz zrobić coś takiego
Ten kod jest testowany i działa w produkcji. Pełna treść testów dostępna jest tutaj https://gist.github.com/dmichael/5710968
Należy pamiętać, że dla każdego żądania konieczne będzie utworzenie nowego klienta ze względu na
conn.SetDeadline
odwołanie do punktu w przyszłościtime.Now()
źródło
Jeśli chcesz to zrobić na żądanie, obsługa błędów została zignorowana ze względu na zwięzłość:
źródło
http.Client.Timeout
.Szybki i brudny sposób:
To jest mutacja stanu globalnego bez jakiejkolwiek koordynacji. Jednak może to być w porządku dla twojego modułu pobierania adresów URL. W przeciwnym razie utwórz prywatną instancję
http.RoundTripper
:Nic powyżej nie zostało przetestowane.
źródło
http.DefaultTransport.(*http.Transport).ResponseHeaderTimeout = time.Second * 45
pomóż mi dużo w teście pisania dla przekroczenia limitu czasu żądania. Dziękuję Ci bardzo.Możesz użyć https://github.com/franela/goreq, który obsługuje limity czasu w modny i prosty sposób.
źródło
Może to pomóc, ale zauważ, że
ResponseHeaderTimeout
zaczyna się dopiero po ustanowieniu połączenia.źródło