continue with not modified if only all upstreams respond not modified

This commit is contained in:
guochao 2025-02-06 00:33:45 +08:00
parent 5aebbb1884
commit 2b5f214f2a

View File

@ -416,15 +416,18 @@ func (server *Server) fastesUpstream(r *http.Request, lastModified time.Time) (r
returnLock := &sync.Mutex{}
upstreams := len(server.Upstreams)
cancelFuncs := make([]func(), upstreams)
selectedCh := make(chan int, 1)
selectedOnce := &sync.Once{}
updateCh := make(chan int, 1)
updateOnce := &sync.Once{}
notModifiedCh := make(chan int, 1)
notModifiedOnce := &sync.Once{}
wg := &sync.WaitGroup{}
wg.Add(len(server.Upstreams))
defer close(selectedCh)
defer close(updateCh)
for idx := range server.Upstreams {
idx := idx
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
cancelFuncs[idx] = cancel
logger := slog.With("upstreamIdx", idx)
@ -446,7 +449,7 @@ func (server *Server) fastesUpstream(r *http.Request, lastModified time.Time) (r
if response == nil {
return
}
if response.StatusCode != http.StatusOK {
if response.StatusCode != http.StatusOK && response.StatusCode != http.StatusNotModified {
return
}
locked := returnLock.TryLock()
@ -455,9 +458,17 @@ func (server *Server) fastesUpstream(r *http.Request, lastModified time.Time) (r
}
defer returnLock.Unlock()
selectedOnce.Do(func() {
if response.StatusCode == http.StatusNotModified {
notModifiedOnce.Do(func() {
resultResponse, resultCh, resultErr = response, ch, err
selectedCh <- idx
notModifiedCh <- idx
})
return
}
updateOnce.Do(func() {
resultResponse, resultCh, resultErr = response, ch, err
updateCh <- idx
for cancelIdx, cancel := range cancelFuncs {
if cancelIdx == idx {
@ -474,11 +485,14 @@ func (server *Server) fastesUpstream(r *http.Request, lastModified time.Time) (r
wg.Wait()
resultIdx = -1
select {
case idx := <-selectedCh:
if idx, ok := <-updateCh; ok {
resultIdx = idx
slog.With("upstreamIdx", resultIdx).Debug("upstream selected")
default:
} else if idx, ok := <-notModifiedCh; ok {
resultIdx = idx
slog.With("upstreamIdx", resultIdx).Debug("upstream selected(not modified)")
} else {
slog.Debug("no valid upstream found")
}