more features

This commit is contained in:
Para Dox
2025-05-28 23:35:14 +07:00
parent 23bf18eb83
commit d78f41e521

View File

@@ -1217,6 +1217,7 @@ func handleRequest(w http.ResponseWriter, r *http.Request, backends []Backend, c
// Track if we've already sent a response // Track if we've already sent a response
var responseHandled atomic.Bool var responseHandled atomic.Bool
var firstBackendStartTime atomic.Pointer[time.Time] var firstBackendStartTime atomic.Pointer[time.Time]
primaryResponseChan := make(chan struct{}, 1) // Signal when primary gets a response
for _, backend := range backends { for _, backend := range backends {
// Skip secondary backends for stateful methods // Skip secondary backends for stateful methods
@@ -1250,9 +1251,8 @@ func handleRequest(w http.ResponseWriter, r *http.Request, backends []Backend, c
select { select {
case <-delayTimer.C: case <-delayTimer.C:
// Timer expired, primary is slow, proceed with secondary request // Timer expired, primary is slow, proceed with secondary request
case <-responseChan: case <-primaryResponseChan:
// Someone (likely primary) already responded fast enough // Primary already got a response, skip secondary
// Skip sending to secondary backend
delayTimer.Stop() delayTimer.Stop()
// Still record that we skipped this backend // Still record that we skipped this backend
@@ -1301,6 +1301,15 @@ func handleRequest(w http.ResponseWriter, r *http.Request, backends []Backend, c
} }
defer resp.Body.Close() defer resp.Body.Close()
// Signal primary response immediately for secondary backends to check
if b.Role == "primary" && resp.StatusCode < 400 {
select {
case primaryResponseChan <- struct{}{}:
default:
// Channel already has a signal
}
}
// Read response body // Read response body
respBody, err := io.ReadAll(resp.Body) respBody, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {