Калі 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 мусяць быць не-nil, цалкам наладжанымі і бяспечнымі пры адначасовасці выканаўцамі кругоў. Стварайце кожны праксі-транспарт перад публікацыяй і не змяняйце яго канфігурацыю, пакуль запыты яго выкарыстоўваюць.

Блакіроўка абараняе толькі здымак указальніка, таму павольны запыт не ўтрымлівае блакіроўку маршрутызацыі ўвесь час сеткавага абмену. Запыт, які ўжо выкарыстоўвае папярэдні здымак, працягвае на тым транспарце; пераключэнне не паўтарае яго і не пераносіць яго злучэнне.

Захоўвайце і выводзьце старыя транспарты праз абмежаваны жыццёвы цыкл праграмы, даючы магчымасць завяршыць працу ў працэсе і закрываючы прастойныя пулы, калі гэта мэтазгодна. Перанакіраванне можа выклікаць яшчэ адзін RoundTrip пасля пераключэння. Калі ўвесь працоўны працэс патрабуе аднаго маршруту, прызначце яго на мяжы працоўнага працэсу замест таго, каб змяняць гэты агульны селектар на паўдарозе.

Падобныя артыкулы