Go HTTP proxy útvonalak váltása a Client.Transport módosítása nélkül
Használjon szinkronizált RoundTripper-burkot egy új, konfigurált proxy átviteli réteg közzétételére anélkül, hogy módosítaná egy élő http.Client mezőt.
Ha egy http.Client már megosztott az egyidejű kérések között, tartsa stabilan a Transport mezőjét. A burok szinkronizálhatja, melyik teljesen konfigurált átviteli réteg kapja az egyes későbbi oda-vissza köröket:
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()
}A net/http és a sync használatával inicializálja, mielőtt közzéteszi a klienst:
slot := &routeSlot{current: initialTransport}
client := &http.Client{Transport: slot}
slot.Set(nextTransport)Az initialTransport és a nextTransport nem lehet nil, teljesen konfiguráltnak és egyidejűség szempontjából biztonságosnak kell lennie. Minden proxy átviteli réteget a közzététele előtt építsen fel, és hagyja a konfigurációját változatlanul, amíg a kérések használják.
A zár csak a mutató pillanatképét védi, így egy lassú kérés nem tartja a továbbítási zárat a teljes hálózati cseréje alatt. Az előző pillanatképet használó kérés tovább halad azon az átviteli rétegen; a váltás nem játssza újra és nem helyezi át a kapcsolatát.
Tartsa meg és vonja ki a régi átviteli rétegeket az alkalmazás korlátozott életciklusán keresztül, engedve a folyamatban lévő munkát befejeződni, és zárja be a tétlen poolokat, amikor indokolt. Egy átirányítás a váltás után újabb RoundTripet okozhat. Ha egy teljes munkafolyamat egy útvonalat igényel, azt a munkafolyamat határán rendelje hozzá, ahelyett hogy ezt a megosztott választót félúton módosítaná.