diff options
author | antirez <antirez@gmail.com> | 2014-05-14 00:15:52 +0200 |
---|---|---|
committer | antirez <antirez@gmail.com> | 2014-05-14 00:15:52 +0200 |
commit | cdf2271c5b8c8574f8441cd1214ed28d9cb583db (patch) | |
tree | af139ac2a76e24235668d10174b9cc57cd3f9838 /tests/support | |
parent | bae30479fba0f260dd65f2e8218ea69b5090f6b8 (diff) | |
download | redis-cdf2271c5b8c8574f8441cd1214ed28d9cb583db.tar.gz |
cluster.tcl: saner error handling.
Better handling of connection errors in order to update the table and
recovery, populate the startup nodes table after fetching the list of
nodes.
More work to do about it, it is still not as reliable as
redis-rb-cluster implementation which is the minimal reference
implementation for Redis Cluster clients.
Diffstat (limited to 'tests/support')
-rw-r--r-- | tests/support/cluster.tcl | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/tests/support/cluster.tcl b/tests/support/cluster.tcl index 90e8352dd..79d9244d0 100644 --- a/tests/support/cluster.tcl +++ b/tests/support/cluster.tcl @@ -56,14 +56,21 @@ proc redis_cluster {nodes} { proc ::redis_cluster::__method__refresh_nodes_map {id} { # Contact the first responding startup node. set idx 0; # Index of the node that will respond. + set errmsg {} foreach start_node $::redis_cluster::startup_nodes($id) { lassign [split $start_node :] start_host start_port if {[catch { + set r {} set r [redis $start_host $start_port] set nodes_descr [$r cluster nodes] $r close - }]} { + puts $e + } e]} { + if {$r ne {}} {catch {$r close}} incr idx + if {[string length $errmsg] < 200} { + append errmsg " $start_node: $e" + } continue ; # Try next. } else { break; # Good node found. @@ -71,7 +78,7 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { } if {$idx == [llength $::redis_cluster::startup_nodes($id)]} { - error "No good startup node found." + error "No good startup node found. $errmsg" } # Put the node that responded as first in the list if it is not @@ -113,6 +120,7 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { link $link \ ] dict set nodes $addr $node + lappend ::redis_cluster::startup_nodes($id) $addr } set ::redis_cluster::nodes($id) $nodes @@ -127,6 +135,9 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { } } } + + # Only retain unique entries in the startup nodes list + set ::redis_cluster::startup_nodes($id) [lsort -unique $::redis_cluster::startup_nodes($id)] } # Free a redis_cluster handle. @@ -166,13 +177,16 @@ proc ::redis_cluster::__dispatch__ {id method args} { } # Execute the command in the node we think is the slot owner. - set retry 10 + set retry 100 while {[incr retry -1]} { if {$retry < 5} {after 100} set node [dict get $::redis_cluster::nodes($id) $node_addr] set link [dict get $node link] if {[catch {$link $method {*}$args} e]} { - if {[string range $e 0 4] eq {MOVED}} { + if {$link eq {} || \ + [string range $e 0 4] eq {MOVED} || \ + [string range $e 0 2] eq {I/O} \ + } { # MOVED redirection. ::redis_cluster::__method__refresh_nodes_map $id set node_addr [dict get $::redis_cluster::slots($id) $slot] |