Cambiar rutas de proxy HTTP de Go sen modificar Client.Transport
Use un envoltorio RoundTripper sincronizado para publicar un novo transporte proxy configurado sen modificar un campo http.Client en uso.
Se un http.Client xa é compartido por peticións simultáneas, manteña o seu campo Transport estable. Un envoltorio pode sincronizar que transporte totalmente configurado recibe cada percorrido posterior:
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()
}Con net/http e sync, inicialíceo antes de publicar o cliente:
slot := &routeSlot{current: initialTransport}
client := &http.Client{Transport: slot}
slot.Set(nextTransport)initialTransport e nextTransport deben ser executores de percorridos non nulos, totalmente configurados e seguros fronte á concorrencia. Constrúa cada transporte proxy antes de publicalo e deixe a súa configuración sen cambios mentres as peticións o usan.
O bloqueo só protexe a instantánea do punteiro, así que unha petición lenta non retén o bloqueo de encamiñamento durante todo o seu intercambio de rede. Unha petición que xa usa a instantánea anterior continúa nese transporte; o cambio non a repite nin move a súa conexión.
Conserve e retire os transportes antigos durante o ciclo de vida acoutado da aplicación, permitindo que o traballo en curso remate e pechando os pools inactivos cando corresponda. Unha redirección pode provocar outro RoundTrip despois dun cambio. Se todo un fluxo de traballo precisa unha ruta, asígnea en a fronteira do fluxo de traballo en lugar de cambiar este selector compartido a medio camiño.