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.

Artigos relacionados