Jika http.Client sudah dikongsi oleh permintaan serentak, kekalkan medan Transport-nya stabil. Pembalut boleh menyegerakkan pengangkut mana yang dikonfigurasi sepenuhnya yang diterima setiap pusingan seterusnya:

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, mulakannya sebelum menerbitkan klien:

slot := &routeSlot{current: initialTransport}
client := &http.Client{Transport: slot}

slot.Set(nextTransport)

initialTransport dan nextTransport mestilah bukan nil, dikonfigurasi sepenuhnya dan selamat dari segi keserentakan. Bina setiap pengangkut proksi sebelum menerbitkannya, dan biarkan konfigurasinya tidak berubah semasa permintaan menggunakannya.

Kunci hanya melindungi petikan penunjuk, jadi permintaan perlahan tidak memegang kunci penghalaan sepanjang pertukaran rangkaiannya. Permintaan yang sudah menggunakan petikan sebelumnya meneruskan pada pengangkut itu; pertukaran itu tidak mengulanginya atau memindahkan sambungannya.

Kekalkan dan persarakan pengangkut lama melalui kitaran hayat aplikasi yang terbatas, biarkan kerja yang sedang berjalan selesai dan tutup kolam melahu apabila sesuai. Ubah hala boleh menyebabkan RoundTrip lain selepas pertukaran. Jika keseluruhan aliran kerja memerlukan satu laluan, tetapkan laluan itu di sempadan aliran kerja daripada menukar pemilih kongsi ini di pertengahan jalan.

Artikel berkaitan