Comutarea rutelor proxy HTTP Go fără a modifica Client.Transport
Folosiți un înveliș RoundTripper sincronizat pentru a publica un transport proxy nou configurat fără a modifica un câmp http.Client activ.
Dacă un http.Client este deja partajat de cereri concurente, păstrați câmpul său Transport stabil. Un înveliș poate sincroniza ce transport complet configurat primește fiecare tură ulterioară:
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()
}Cu net/http și sync, inițializați-l înainte de a publica clientul:
slot := &routeSlot{current: initialTransport}
client := &http.Client{Transport: slot}
slot.Set(nextTransport)initialTransport și nextTransport trebuie să fie non-nil, complet configurate și sigure din punctul de vedere al concurenței. Construiți fiecare transport proxy înainte de a-l publica și lăsați configurația neschimbată cât timp cererile îl folosesc.
Blocajul protejează doar instantaneul pointerului, așa că o cerere lentă nu ține blocajul de rutare pe toată durata schimbului său de rețea. O cerere care folosește deja instantaneul anterior continuă pe acel transport; comutarea nu o reia și nu îi mută conexiunea.
Păstrați și retrageți transporturile vechi prin ciclul de viață limitat al aplicației, lăsând lucrul în curs să se termine și închizând pool-urile inactive când este potrivit. O redirecționare poate provoca un alt RoundTrip după o comutare. Dacă un întreg flux de lucru necesită o singură rută, atribuiți-o la granița fluxului de lucru în loc să schimbați acest selector partajat la jumătatea drumului.