ປ່ຽນເສັ້ນທາງ proxy HTTP ຂອງ Go ໂດຍບໍ່ປ່ຽນ Client.Transport
ໃຊ້ wrapper RoundTripper ທີ່ຊິງໂຄຣນາຍ ເພື່ອເຜີຍແຜ່ transport proxy ທີ່ຕັ້ງຄ່າໃໝ່ ໂດຍບໍ່ປ່ຽນ field http.Client ທີ່ກຳລັງໃຊ້ງານ.
ຖ້າ http.Client ຖືກແບ່ງປັນໂດຍ request ທີ່ເກີດຂຶ້ນພ້ອມກັນແລ້ວ, ຮັກສາ field Transport ຂອງມັນໃຫ້ຄົງທີ່. Wrapper ສາມາດຊິງໂຄຣໄນວ່າ 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, ເລີ່ມຕົ້ນມັນກ່ອນທີ່ຈະເຜີຍແຜ່ client:
slot := &routeSlot{current: initialTransport}
client := &http.Client{Transport: slot}
slot.Set(nextTransport)initialTransport ແລະ nextTransport ຕ້ອງເປັນ non-nil, ຕັ້ງຄ່າຢ່າງເຕັມທີ່ ແລະ ປອດໄພຕໍ່ການເຮັດວຽກພ້ອມກັນ. ສ້າງ transport proxy ແຕ່ລະອັນກ່ອນເຜີຍແຜ່, ແລະ ປ່ອຍໃຫ້ການຕັ້ງຄ່າຂອງມັນບໍ່ປ່ຽນແປງໃນຂະນະທີ່ request ໃຊ້ມັນຢູ່.
ການລັອກປົກປ້ອງພຽງແຕ່ snapshot ຂອງ pointer, ດັ່ງນັ້ນ request ທີ່ຊ້າຈະບໍ່ຖືກລັອກການເສັ້ນທາງຕະຫຼອດການແລກປ່ຽນເຄືອຂ່າຍທັງໝົດ. Request ທີ່ໃຊ້ snapshot ກ່ອນໜ້ານັ້ນຈະສືບຕໍ່ເທິງ transport ນັ້ນ; ການປ່ຽນບໍ່ໄດ້ເຮັດຊ້ຳ ຫຼື ຍ້າຍການເຊື່ອມຕໍ່ຂອງມັນ.
ເກັບຮັກສາ ແລະ ປົດ transport ເກົ່າຜ່ານ lifecycle ທີ່ມີຂອບເຂດຂອງແອັບພລິເຄຊັນ, ປ່ອຍໃຫ້ວຽກທີ່ກຳລັງເຮັດສຳເລັດ ແລະ ປິດ pool ທີ່ຫວ່າງເມື່ອເໝາະສົມ. ການ redirect ສາມາດເຮັດໃຫ້ເກີດ RoundTrip ອີກອັນໜຶ່ງຫຼັງການປ່ຽນ. ຖ້າ workflow ທັງໝົດຕ້ອງການເສັ້ນທາງດຽວ, ກຳນົດເສັ້ນທາງນັ້ນທີ່ ຂອບເຂດຂອງ workflow ແທນທີ່ຈະປ່ຽນ selector ທີ່ແບ່ງປັນນີ້ກາງທາງ.