Changer d'itinéraires de proxy HTTP Go sans modifier Client.Transport
Utilisez un enveloppe RoundTripper synchronisée pour publier un nouveau transport proxy configuré sans modifier un champ http.Client en service.
Si un http.Client est déjà partagé par des requêtes concurrentes, gardez son champ Transport stable. Une enveloppe peut synchroniser quel transport entièrement configuré reçoit chaque aller-retour ultérieur :
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()
}Avec net/http et sync, initialisez-la avant de publier le client :
slot := &routeSlot{current: initialTransport}
client := &http.Client{Transport: slot}
slot.Set(nextTransport)initialTransport et nextTransport doivent être des exécuteurs d'aller-retour non nuls, entièrement configurés et sûrs vis-à-vis de la concurrence. Construisez chaque transport proxy avant de le publier, et laissez sa configuration inchangée pendant que des requêtes l'utilisent.
Le verrou ne protège que l'instantané du pointeur, si bien qu'une requête lente ne retient pas le verrou de routage pendant tout son échange réseau. Une requête qui utilise déjà l'instantané précédent continue sur ce transport ; le changement ne la rejoue pas et ne déplace pas sa connexion.
Conservez et réformez les anciens transports selon le cycle de vie borné de l'application, en laissant le travail en cours se terminer et en fermant les pools inactifs le cas échéant. Une redirection peut provoquer un autre RoundTrip après un changement. Si un flux de travail entier exige un seul itinéraire, attribuez-le à la frontière du flux de travail plutôt que de changer ce sélecteur partagé en cours de route.