Om en http.Client redan delas av samtidiga förfrågningar, håll dess Transport-fält stabilt. En wrapp kan synkronisera vilken fullt konfigurerad transport varje senare tur får:

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 och sync, initiera den innan klienten publiceras:

slot := &routeSlot{current: initialTransport}
client := &http.Client{Transport: slot}

slot.Set(nextTransport)

initialTransport och nextTransport måste vara icke-nil, fullt konfigurerade och samtidighetssäkra turexekverare. Bygg varje proxytransport innan den publiceras, och lämna dess konfiguration oförändrad medan förfrågningar använder den.

Låset skyddar bara pekarens ögonblicksbild, så en långsam förfrågan håller inte routinglåset under hela sitt nätverksutbyte. En förfrågan som redan använder den föregående ögonblicksbilden fortsätter på den transporten; bytet spelar inte upp den igen eller flyttar dess anslutning.

Behåll och avveckla gamla transporter genom applikationens begränsade livscykel, låt pågående arbete slutföras och stäng inaktiva pooler när det är lämpligt. En omdirigering kan orsaka en ny RoundTrip efter ett byte. Om ett helt arbetsflöde kräver en väg, tilldela den vid arbetsflödets gräns i stället för att ändra denna delade väljare mitt i.

Relaterade artiklar