अगर कोई 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 कर सकता है। यदि पूरे वर्कफ़्लो को एक रूट चाहिए, तो इस साझा सिलेक्टर को बीच में बदलने के बजाय वर्कफ़्लो की सीमा पर वह रूट निर्दिष्ट करें।

संबंधित लेख