Ak je http.Client už zdieľaný súbežnými požiadavkami, udržujte jeho pole Transport stabilné. Obal dokáže synchronizovať, ktorý plne nakonfigurovaný transport dostane každé ďalšie kolo:

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()
}

Pomocou net/http a sync ho inicializujte pred publikovaním klienta:

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

slot.Set(nextTransport)

initialTransport a nextTransport musia byť non-nil, plne nakonfigurované a voči súbežnosti bezpečné vykonávateľe kôl. Každý proxy transport zostavte pred jeho publikovaním a jeho konfiguráciu nemeňte, kým ho požiadavky používajú.

Zámok chráni len snímku ukazovateľa, takže pomalá požiadavka nedrží smerovací zámok počas celej svojej sieťovej výmeny. Požiadavka, ktorá už používa predchádzajúcu snímku, pokračuje na tomto transporte; prepnutie ju nespustí znova ani nepresunie jej spojenie.

Staré transporty uchovávajte a vyraďujte v rámci obmedzeného životného cyklu aplikácie, nechajte bežiacu prácu dokončiť a podľa potreby zatvorte nečinné fondy. Presmerovanie môže po prepnutí vyvolať ďalší RoundTrip. Ak celý pracovný postup vyžaduje jednu trasu, priraďte ju na hranici pracovného postupu, namiesto toho, aby ste tento zdieľaný selektor menili v polovici.

Súvisiace články