Ganti rute proxy HTTP Go tanpa mengubah Client.Transport
Gunakan pembungkus RoundTripper tersinkronisasi untuk menerbitkan transport proxy baru yang terkonfigurasi tanpa mengubah field http.Client yang sedang aktif.
Jika sebuah http.Client sudah dipakai bersama oleh permintaan bersamaan, jaga field Transport-nya tetap stabil. Pembungkus dapat menyinkronkan transport mana yang terkonfigurasi penuh yang diterima setiap perjalanan berikutnya:
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()
}Dengan net/http dan sync, inisialisasi sebelum menerbitkan klien:
slot := &routeSlot{current: initialTransport}
client := &http.Client{Transport: slot}
slot.Set(nextTransport)initialTransport dan nextTransport harus non-nil, terkonfigurasi penuh, dan aman untuk konkurensi. Bangun setiap transport proxy sebelum menerbitkannya, dan biarkan konfigurasinya tidak berubah selama permintaan memakainya.
Kunci hanya melindungi cuplikan pointer, sehingga permintaan lambat tidak menahan kunci perutean selama seluruh pertukaran jaringannya. Permintaan yang sudah memakai cuplikan sebelumnya berlanjut pada transport itu; penggantian tidak memutarnya ulang atau memindahkan koneksinya.
Pertahankan dan pensiunkan transport lama melalui siklus hidup aplikasi yang terbatas, membiarkan pekerjaan yang sedang berjalan selesai dan menutup kumpulan menganggur bila perlu. Pengalihan dapat menyebabkan RoundTrip lain setelah penggantian. Jika seluruh alur kerja memerlukan satu rute, tetapkan rute itu di batas alur kerja alih-alih mengubah pemilih bersama ini di tengah jalan.