Keisti Go HTTP proxy maršrutus nekeičiant Client.Transport
Naudokite sinchronizuotą RoundTripper apvalkalą, kad paskelbtumėte naują sukonfigūruotą proxy transportą nekeisdami veikiančio http.Client lauko.
Jei http.Client jau dalijamasi lygiagrečių užklausų, palaikykite jo Transport lauką stabilų. Apvalkalas gali sinchronizuoti, kurį visiškai sukonfigūruotą transportą gauna kiekvienas vėlesnis reisas:
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()
}Naudodami net/http ir sync, inicializuokite jį prieš paskelbdami klientą:
slot := &routeSlot{current: initialTransport}
client := &http.Client{Transport: slot}
slot.Set(nextTransport)initialTransport ir nextTransport turi būti ne nil, visiškai sukonfigūruoti ir lygiagretumui saugūs reisų vykdytojai. Kurkite kiekvieną proxy transportą prieš jį paskelbdami ir nekeiskite jo konfigūracijos, kol užklausos jį naudoja.
Užraktas saugo tik rodyklės momentinę kopiją, todėl lėta užklausa nelaiko maršrutizavimo užrakto viso tinklo mainų metu. Užklausa, kuri jau naudoja ankstesnę kopiją, tęsiasi tame transporte; perjungimas jos nekartoja ir neperkelia jos ryšio.
Išsaugokite ir atsisakykite senų transportų per apribotą programos gyvavimo ciklą, leiskite vykdomam darbui pasibaigti ir prireikus uždarykite neveiksnius telkinius. Peradresavimas po perjungimo gali sukelti dar vieną RoundTrip. Jei visam darbo srautui reikia vieno maršruto, priskirkite jį darbo srauto riboje, o ne keiskite šį bendrą selektorių įpusėjus.