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.

Artikel terkait