more features
This commit is contained in:
@@ -479,6 +479,7 @@ func (sc *StatsCollector) printSummary() {
|
|||||||
|
|
||||||
// Print per-backend statistics
|
// Print per-backend statistics
|
||||||
fmt.Printf("\nPer-Backend Response Time Comparison:\n")
|
fmt.Printf("\nPer-Backend Response Time Comparison:\n")
|
||||||
|
fmt.Printf("Note: 'User Latency' = actual time users wait; 'Backend Time' = winning backend's response time\n")
|
||||||
fmt.Printf("%-20s %10s %10s %10s %10s %10s %10s %10s\n",
|
fmt.Printf("%-20s %10s %10s %10s %10s %10s %10s %10s\n",
|
||||||
"Backend", "Count", "Min", "Avg", "Max", "p50", "p90", "p99")
|
"Backend", "Count", "Min", "Avg", "Max", "p50", "p90", "p99")
|
||||||
fmt.Printf("%s\n", strings.Repeat("-", 100))
|
fmt.Printf("%s\n", strings.Repeat("-", 100))
|
||||||
@@ -515,7 +516,7 @@ func (sc *StatsCollector) printSummary() {
|
|||||||
formatDuration(p50), formatDuration(p90), formatDuration(p99))
|
formatDuration(p50), formatDuration(p90), formatDuration(p99))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then show the winner's time (what backend actually took)
|
// Then show the backend time (what backend actually took)
|
||||||
if len(sc.firstResponseDurations) > 0 {
|
if len(sc.firstResponseDurations) > 0 {
|
||||||
firstRespDurations := make([]time.Duration, len(sc.firstResponseDurations))
|
firstRespDurations := make([]time.Duration, len(sc.firstResponseDurations))
|
||||||
copy(firstRespDurations, sc.firstResponseDurations)
|
copy(firstRespDurations, sc.firstResponseDurations)
|
||||||
@@ -542,7 +543,7 @@ func (sc *StatsCollector) printSummary() {
|
|||||||
p99 := firstRespDurations[p99idx]
|
p99 := firstRespDurations[p99idx]
|
||||||
|
|
||||||
fmt.Printf("%-20s %10d %10s %10s %10s %10s %10s %10s\n",
|
fmt.Printf("%-20s %10d %10s %10s %10s %10s %10s %10s\n",
|
||||||
"Winner's Time", len(firstRespDurations),
|
"Backend Time", len(firstRespDurations),
|
||||||
formatDuration(min), formatDuration(avg), formatDuration(max),
|
formatDuration(min), formatDuration(avg), formatDuration(max),
|
||||||
formatDuration(p50), formatDuration(p90), formatDuration(p99))
|
formatDuration(p50), formatDuration(p90), formatDuration(p99))
|
||||||
fmt.Printf("%s\n", strings.Repeat("-", 100))
|
fmt.Printf("%s\n", strings.Repeat("-", 100))
|
||||||
@@ -818,7 +819,7 @@ func (sc *StatsCollector) printSummary() {
|
|||||||
formatDuration(p50), formatDuration(p90), formatDuration(p99))
|
formatDuration(p50), formatDuration(p90), formatDuration(p99))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show Winner's Time statistics for this method
|
// Show Backend Time statistics for this method
|
||||||
if methodFirstDurations, exists := sc.methodFirstResponseDurations[method]; exists && len(methodFirstDurations) > 0 {
|
if methodFirstDurations, exists := sc.methodFirstResponseDurations[method]; exists && len(methodFirstDurations) > 0 {
|
||||||
// Make a copy and sort
|
// Make a copy and sort
|
||||||
durations := make([]time.Duration, len(methodFirstDurations))
|
durations := make([]time.Duration, len(methodFirstDurations))
|
||||||
@@ -852,7 +853,7 @@ func (sc *StatsCollector) printSummary() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf(" %-20s %10d %10s %10s %10s %10s %10s %10s\n",
|
fmt.Printf(" %-20s %10d %10s %10s %10s %10s %10s %10s\n",
|
||||||
"Winner's Time", len(durations),
|
"Backend Time", len(durations),
|
||||||
formatDuration(min), formatDuration(avg), formatDuration(max),
|
formatDuration(min), formatDuration(avg), formatDuration(max),
|
||||||
formatDuration(p50), formatDuration(p90), formatDuration(p99))
|
formatDuration(p50), formatDuration(p90), formatDuration(p99))
|
||||||
fmt.Printf(" %s\n", strings.Repeat("-", 98))
|
fmt.Printf(" %s\n", strings.Repeat("-", 98))
|
||||||
@@ -1197,6 +1198,9 @@ func handleRequest(w http.ResponseWriter, r *http.Request, backends []Backend, c
|
|||||||
go func(b Backend) {
|
go func(b Backend) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
|
// Track when this goroutine actually starts processing
|
||||||
|
goroutineStartTime := time.Now()
|
||||||
|
|
||||||
// If this is a secondary backend, wait for p50 delay
|
// If this is a secondary backend, wait for p50 delay
|
||||||
if b.Role != "primary" {
|
if b.Role != "primary" {
|
||||||
select {
|
select {
|
||||||
@@ -1220,6 +1224,7 @@ func handleRequest(w http.ResponseWriter, r *http.Request, backends []Backend, c
|
|||||||
Backend: b.Name,
|
Backend: b.Name,
|
||||||
Error: err,
|
Error: err,
|
||||||
Method: method,
|
Method: method,
|
||||||
|
Duration: time.Since(goroutineStartTime), // Include any wait time
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -1241,7 +1246,7 @@ func handleRequest(w http.ResponseWriter, r *http.Request, backends []Backend, c
|
|||||||
if !errors.Is(err, context.Canceled) {
|
if !errors.Is(err, context.Canceled) {
|
||||||
statsChan <- ResponseStats{
|
statsChan <- ResponseStats{
|
||||||
Backend: b.Name,
|
Backend: b.Name,
|
||||||
Duration: reqDuration,
|
Duration: reqDuration, // Keep backend-specific duration
|
||||||
Error: err,
|
Error: err,
|
||||||
Method: method,
|
Method: method,
|
||||||
}
|
}
|
||||||
@@ -1255,7 +1260,7 @@ func handleRequest(w http.ResponseWriter, r *http.Request, backends []Backend, c
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
statsChan <- ResponseStats{
|
statsChan <- ResponseStats{
|
||||||
Backend: b.Name,
|
Backend: b.Name,
|
||||||
Duration: reqDuration,
|
Duration: reqDuration, // Keep backend-specific duration
|
||||||
Error: err,
|
Error: err,
|
||||||
Method: method,
|
Method: method,
|
||||||
}
|
}
|
||||||
@@ -1265,7 +1270,7 @@ func handleRequest(w http.ResponseWriter, r *http.Request, backends []Backend, c
|
|||||||
statsChan <- ResponseStats{
|
statsChan <- ResponseStats{
|
||||||
Backend: b.Name,
|
Backend: b.Name,
|
||||||
StatusCode: resp.StatusCode,
|
StatusCode: resp.StatusCode,
|
||||||
Duration: reqDuration,
|
Duration: reqDuration, // This is the backend-specific duration
|
||||||
Method: method,
|
Method: method,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user