Ich mache einen URL-Abruf in Go und habe eine Liste der abzurufenden URLs. Ich sende http.Get()
Anfragen an jede URL und erhalte deren Antwort.
resp,fetch_err := http.Get(url)
Wie kann ich für jede Get-Anfrage ein benutzerdefiniertes Zeitlimit festlegen? (Die Standardzeit ist sehr lang und das macht meinen Abruf sehr langsam.) Ich möchte, dass mein Abruf eine Zeitüberschreitung von ca. 40-45 Sekunden hat. Danach sollte er "Zeitüberschreitung bei Anforderung" zurückgeben und zur nächsten URL übergehen.
Wie kann ich das erreichen?
Antworten:
Anscheinend hat http.Client in Go 1.3 das Feld Timeout
Das ist der Trick für mich.
quelle
Get
einen Fehler zurück? Ich bin ein wenig verwirrt, weil der Godoc fürClient
sagt: Der Timer läuft nach Get, Head, Post oder Do return weiter und unterbricht das Lesen der Response.Body. Bedeutet das also, dass entwederGet
oder das LesenResponse.Body
durch einen Fehler unterbrochen werden könnte?http.Client.Timeout
vs.http.Transport.ResponseHeaderTimeout
?http.Client.Timeout
die Zeit zum Lesen des Antworttextes,http.Transport.ResponseHeaderTimeout
schließt ihn nicht ein.Sie müssen Ihren eigenen Client mit Ihrem eigenen Transport einrichten, der eine benutzerdefinierte Wählfunktion verwendet, die DialTimeout umschließt .
So etwas wie (völlig ungetestet ) diese :
quelle
Um die Antwort von Volker zu ergänzen, können Sie Folgendes tun, wenn Sie zusätzlich zum Zeitlimit für die Verbindung auch das Lese- / Schreibzeitlimit festlegen möchten
Dieser Code wird getestet und funktioniert in der Produktion. Die vollständige Liste der Tests finden Sie hier https://gist.github.com/dmichael/5710968
Beachten Sie, dass Sie für jede Anforderung einen neuen Client erstellen müssen, da
conn.SetDeadline
dieser auf einen Punkt in der Zukunft verweisttime.Now()
quelle
Wenn Sie dies auf Anfrage tun möchten, wird die Fehlerbehandlung der Kürze halber ignoriert:
quelle
http.Client.Timeout
.Ein schneller und schmutziger Weg:
Dies mutiert den globalen Staat ohne jegliche Koordination. Möglicherweise ist es jedoch für Ihren URL-Abruf in Ordnung. Andernfalls erstellen Sie eine private Instanz von
http.RoundTripper
:Nichts oben wurde getestet.
quelle
http.DefaultTransport.(*http.Transport).ResponseHeaderTimeout = time.Second * 45
Helfen Sie mir viel beim Schreiben eines Tests für das Zeitlimit für Anfragen. Vielen Dank.Sie können https://github.com/franela/goreq verwenden , um Zeitüberschreitungen auf einfache und einfache Weise zu behandeln.
quelle
Dies kann hilfreich sein, aber beachten Sie, dass dies
ResponseHeaderTimeout
erst beginnt, nachdem die Verbindung hergestellt wurde.quelle