تبديل مسارات وكيل HTTP في Go دون تعديل Client.Transport
استخدم غلاف RoundTripper متزامنًا لنشر ناقل وكيل مُكوَّن جديد دون تعديل حقل http.Client قيد التشغيل.
إذا كان 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 آخر بعد التبديل. إذا كان سير عمل كامل يحتاج مسارًا واحدًا، فحدد ذلك المسار عند حدود سير العمل بدلًا من تغيير هذا المحدِّد المشترك في منتصفه.