Skift Go HTTP-proxy-ruter uden at ændre Client.Transport
Brug en synkroniseret RoundTripper-indpakning til at offentliggøre en ny konfigureret proxytransport uden at ændre et aktivt http.Client-felt.
Hvis en http.Client allerede deles af samtidige anmodninger, skal du holde dens Transport-felt stabilt. En indpakning kan synkronisere, hvilken fuldt konfigureret transport hver senere rundtur modtager:
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()
}Med net/http og sync initialiseres den, før klienten offentliggøres:
slot := &routeSlot{current: initialTransport}
client := &http.Client{Transport: slot}
slot.Set(nextTransport)initialTransport og nextTransport skal være ikke-nil, fuldt konfigurerede og samtidighedssikre rundtursudførere. Byg hver proxytransport, før den offentliggøres, og lad dens konfiguration være uændret, mens anmodninger bruger den.
Låsen beskytter kun pointer-snapshottet, så en langsom anmodning holder ikke rutningslåsen under hele sin netværksudveksling. En anmodning, der allerede bruger det foregående snapshot, fortsætter på den transport; skiftet afspiller den ikke eller flytter ikke dens forbindelse.
Behold og udfas gamle transporter gennem applikationens begrænsede livscyklus, lad igangværende arbejde færdiggøre, og luk inaktive pools, når det er passende. En omdirigering kan forårsage endnu en RoundTrip efter et skift. Hvis en hel arbejdsgang kræver én rute, skal du tildele den rute ved arbejdsgangens grænse i stedet for at ændre denne delte vælger midt i den.