|
@@ -52,12 +52,19 @@ func main() {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
for i := 0; i < *concurrency; i++ {
|
|
for i := 0; i < *concurrency; i++ {
|
|
|
|
|
+ // Stagger connection attempts to avoid overwhelming the server's accept backlog
|
|
|
|
|
+ // which can cause timeouts with high concurrency (e.g. > 128 connections)
|
|
|
|
|
+ if i%10 == 0 {
|
|
|
|
|
+ time.Sleep(2 * time.Millisecond)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
wg.Add(1)
|
|
wg.Add(1)
|
|
|
go func(id int) {
|
|
go func(id int) {
|
|
|
defer wg.Done()
|
|
defer wg.Done()
|
|
|
|
|
|
|
|
// Connect
|
|
// Connect
|
|
|
- conn, err := net.DialTimeout("tcp", *addr, 5*time.Second)
|
|
|
|
|
|
|
+ // Increased timeout to handle backlog delays
|
|
|
|
|
+ conn, err := net.DialTimeout("tcp", *addr, 10*time.Second)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
log.Printf("Worker %d failed to connect: %v", id, err)
|
|
log.Printf("Worker %d failed to connect: %v", id, err)
|
|
|
atomic.AddInt64(&failCount, int64(reqsPerConn*2)) // *2 because SET+GET
|
|
atomic.AddInt64(&failCount, int64(reqsPerConn*2)) // *2 because SET+GET
|