Ŝanĝi Go HTTP-proksajn vojojn sen modifi Client.Transport
Uzu sinkronigitan RoundTripper-ĉirkaŭaĵon por publikigi novan agorditan proksan transportilon sen modifi vivan kampon de http.Client.
Se http.Client jam estas dividata de samtempaj petoj, tenu ĝian kampon Transport stabila. Ĉirkaŭaĵo povas sinkronigi, kiun plene agorditan transportilon ricevas ĉiu sekva travojaĝo:
type routeSlot struct {
mu sync.RWMutex
current http.RoundTripper
}
func (s *routeSlot) RoundTrip(r *http.Request) (*http.Response, error) {
s.mu.RLock()
current := s.current
s.mu.RUnlock()
return current.RoundTrip(r)
}
func (s *routeSlot) Set(next http.RoundTripper) {
s.mu.Lock()
s.current = next
s.mu.Unlock()
}Per net/http kaj sync, pravalorigu ĝin antaŭ ol publikigi la klienton:
slot := &routeSlot{current: initialTransport}
client := &http.Client{Transport: slot}
slot.Set(nextTransport)initialTransport kaj nextTransport devas esti ne-nil, plene agorditaj kaj samtempe sekuraj plenumantoj de travojaĝoj. Konstruu ĉiun proksan transportilon antaŭ ol publikigi ĝin, kaj lasu ĝian agordon senŝanĝa dum petoj uzas ĝin.
La ŝloso protektas nur la ĝisdatigobildon de la montrilo, do malrapida peto ne tenas la enkursigan ŝloson dum sia tuta reta interŝanĝo. Peto, kiu jam uzas la antaŭan ĝisdatigobildon, daŭras sur tiu transportilo; la ŝanĝo ne ripetas ĝin nek movas ĝian konekton.
Konservu kaj emeritigu malnovajn transportilojn tra la limigita vivociklo de la aplikaĵo, lasante finiĝi la laboron en progreso kaj fermante neaktivajn basenojn kiam konvene. Alidirektado povas kaŭzi alian RoundTrip post ŝanĝo. Se tuta laborfluo bezonas unu vojon, atribuu tiun vojon ĉe la limo de la laborfluo anstataŭ ŝanĝi ĉi tiun komunan selektilon meze de ĝi.