Alternar rotas de proxy HTTP do Go sem alterar Client.Transport
Use um invólucro RoundTripper sincronizado para publicar um novo transporte de proxy configurado sem alterar um campo http.Client em uso.
Se um http.Client já é compartilhado por solicitações concorrentes, mantenha seu campo Transport estável. Um invólucro pode sincronizar qual transporte totalmente configurado cada ida e volta posterior recebe:
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()
}Com net/http e sync, inicialize-o antes de publicar o cliente:
slot := &routeSlot{current: initialTransport}
client := &http.Client{Transport: slot}
slot.Set(nextTransport)initialTransport e nextTransport devem ser executores de ida e volta não nulos, totalmente configurados e seguros quanto à concorrência. Construa cada transporte de proxy antes de publicá-lo e deixe sua configuração inalterada enquanto as solicitações o usam.
O bloqueio protege apenas o instantâneo do ponteiro, então uma solicitação lenta não retém o bloqueio de roteamento durante toda a troca de rede. Uma solicitação que já usa o instantâneo anterior continua nesse transporte; a troca não a repete nem move sua conexão.
Mantenha e retire transportes antigos durante o ciclo de vida limitado da aplicação, permitindo que o trabalho em andamento termine e fechando pools ociosos quando apropriado. Um redirecionamento pode causar outro RoundTrip após uma troca. Se um fluxo de trabalho inteiro exigir uma rota, atribua-a na fronteira do fluxo de trabalho em vez de alterar este seletor compartilhado no meio do caminho.