Client.Transport మార్చకుండా Go HTTP ప్రాక్సీ మార్గాలను మార్చండి
పనిచేస్తున్న http.Client ఫీల్డ్ను మార్చకుండా కొత్తగా కాన్ఫిగర్ చేసిన ప్రాక్సీ ట్రాన్స్పోర్ట్ను ప్రచురించడానికి సింక్రొనైజ్డ్ RoundTripper ర్యాపర్ను ఉపయోగించండి.
ఒక http.Client ఇప్పటికే సమకాలీన అభ్యర్థనలచే పంచబడి ఉంటే, దాని Transport ఫీల్డ్ను స్థిరంగా ఉంచండి. ప్రతి తదుపరి రౌండ్ ట్రిప్ ఏ పూర్తిగా కాన్ఫిగర్ చేసిన ట్రాన్స్పోర్ట్ను పొందుతుందో ర్యాపర్ సింక్రొనైజ్ చేయగలదు:
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()
}net/http మరియు sync ఉపయోగించి, క్లయింట్ను ప్రచురించే ముందు దాన్ని ప్రారంభించండి:
slot := &routeSlot{current: initialTransport}
client := &http.Client{Transport: slot}
slot.Set(nextTransport)initialTransport మరియు nextTransport non-nil, పూర్తిగా కాన్ఫిగర్ చేయబడినవి మరియు సమకాలీకతకు సురక్షితమైనవి అయి ఉండాలి. ప్రతి ప్రాక్సీ ట్రాన్స్పోర్ట్ను ప్రచురించే ముందు నిర్మించండి, అభ్యర్థనలు దాన్ని ఉపయోగిస్తున్నప్పుడు దాని కాన్ఫిగరేషన్ను మార్చవద్దు.
లాక్ పాయింటర్ స్నాప్షాట్ను మాత్రమే రక్షిస్తుంది, కాబట్టి నెమ్మదైన అభ్యర్థన తన మొత్తం నెట్వర్క్ మార్పిడి అంతా రూటింగ్ లాక్ను పట్టి ఉంచదు. మునుపటి స్నాప్షాట్ను ఉపయోగిస్తున్న అభ్యర్థన ఆ ట్రాన్స్పోర్ట్పై కొనసాగుతుంది; మార్పు దాన్ని మళ్లీ అమలు చేయదు లేదా దాని కనెక్షన్ను కదిలించదు.
పాత ట్రాన్స్పోర్ట్లను అప్లికేషన్ యొక్క పరిమిత జీవిత చక్రం ద్వారా ఉంచి పదవీ విరమణ చేయండి, జరుగుతున్న పని పూర్తవడానికి అనుమతించండి మరియు తగినప్పుడు నిష్క్రియ పూల్లను మూసివేయండి. మార్పు తర్వాత రీడైరెక్ట్ మరో RoundTrip కు కారణం కావచ్చు. మొత్తం వర్క్ఫ్లోకు ఒకే మార్గం అవసరమైతే, ఈ షేర్డ్ సెలెక్టర్ను మధ్యలో మార్చడం బదులు వర్క్ఫ్లో సరిహద్దులో ఆ మార్గాన్ని కేటాయించండి.