From 557e027022f04976f5492665e6bfb3ed34ea795f Mon Sep 17 00:00:00 2001 From: "debing.sun" Date: Mon, 30 Mar 2026 19:50:47 +0800 Subject: [PATCH] Test tcp deadlock fixes (#14946) This fix follows #14667 and #14886 Several tests pipelined large numbers of commands on deferring clients without draining replies. That can fill buffers and stall progress. Fix by draining replies every 500 pipelined requests to avoid TCP stalls. --------- Co-authored-by: oranagra --- .../cluster/tests/17-diskless-load-swapdb.tcl | 9 ++++--- tests/helpers/gen_write_load.tcl | 24 +++++++++++++++++-- tests/unit/memefficiency.tcl | 2 +- tests/unit/type/set.tcl | 17 ++++++++++++- 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/tests/cluster/tests/17-diskless-load-swapdb.tcl b/tests/cluster/tests/17-diskless-load-swapdb.tcl index cb81b9fdb..b25db3930 100644 --- a/tests/cluster/tests/17-diskless-load-swapdb.tcl +++ b/tests/cluster/tests/17-diskless-load-swapdb.tcl @@ -54,9 +54,12 @@ test "Main db not affected when fail to diskless load" { set rd [redis_deferring_client redis $master_id] for {set j 0} {$j < $num} {incr j} { $rd set $j $value - } - for {set j 0} {$j < $num} {incr j} { - $rd read + + if {($j + 1) % 500 == 0} { + for {set i 0} {$i < 500} {incr i} { + $rd read + } + } } # Start the replica again diff --git a/tests/helpers/gen_write_load.tcl b/tests/helpers/gen_write_load.tcl index 8b12d4fd2..d345cc475 100644 --- a/tests/helpers/gen_write_load.tcl +++ b/tests/helpers/gen_write_load.tcl @@ -22,13 +22,18 @@ proc gen_write_load {host port seconds tls {key ""} {size 0} {sleep 0}} { set start_time [clock seconds] set r [redis $host $port 1 $tls] $r client setname LOAD_HANDLER - $r select 9 + $r read + catch { + $r select 9 + $r read + } ;# select 9 will fail in cluster mode # fixed size value if {$size != 0} { set value [string repeat "x" $size] } + set count 0 while 1 { if {$size == 0} { set value [expr rand()] @@ -39,13 +44,28 @@ proc gen_write_load {host port seconds tls {key ""} {size 0} {sleep 0}} { } else { $r set $key $value } + + incr count + if {$count % 500 == 0} { + for {set i 0} {$i < 500} {incr i} { + $r read + } + set count 0 + } + if {[clock seconds]-$start_time > $seconds} { - exit 0 + break } if {$sleep ne 0} { after $sleep } } + + # Read remaining replies + for {set i 0} {$i < $count} {incr i} { + $r read + } + exit 0 } gen_write_load [lindex $argv 0] [lindex $argv 1] [lindex $argv 2] [lindex $argv 3] [lindex $argv 4] [lindex $argv 5] [lindex $argv 6] diff --git a/tests/unit/memefficiency.tcl b/tests/unit/memefficiency.tcl index 2f6406419..ac69f06b2 100644 --- a/tests/unit/memefficiency.tcl +++ b/tests/unit/memefficiency.tcl @@ -345,7 +345,7 @@ run_solo {defrag} { # create big keys with 10k items # Use batching to avoid TCP deadlock set rd [redis_deferring_client] - set batch_size 1000 + set batch_size 100 for {set j 0} {$j < 10000} {incr j} { $rd hset bighash $j [concat "asdfasdfasdf" $j] $rd lpush biglist [concat "asdfasdfasdf" $j] diff --git a/tests/unit/type/set.tcl b/tests/unit/type/set.tcl index c194ee278..86c5e068b 100644 --- a/tests/unit/type/set.tcl +++ b/tests/unit/type/set.tcl @@ -1026,7 +1026,22 @@ foreach type {single multiple single_multiple} { break } } - r srem $myset {*}$members + r deferred 1 + set count 0 + foreach m $members { + r srem $myset $m + incr count + if {$count == 500} { + for {set i 0} {$i < 500} {incr i} { + r read + } + set count 0 + } + } + for {set i 0} {$i < $count} {incr i} { + r read + } + r deferred 0 } proc verify_rehashing_completed_key {myset table_size keys} {