]> git.saurik.com Git - redis.git/commitdiff
Merge branch 'unstable' of github.com:antirez/redis into unstable
authorantirez <antirez@gmail.com>
Wed, 13 Apr 2011 08:39:06 +0000 (10:39 +0200)
committerantirez <antirez@gmail.com>
Wed, 13 Apr 2011 08:39:06 +0000 (10:39 +0200)
TODO
src/cluster.c
src/redis-trib.rb

diff --git a/TODO b/TODO
index 3032392e245dbcf010a977605ad82fae5340ed34..92b6ea9304d1c36d5ec47b27b8f7e0f1eb3ad581 100644 (file)
--- a/TODO
+++ b/TODO
@@ -9,19 +9,13 @@ WARNING: are you a possible Redis contributor?
          us, and *how* exactly this can be implemented to have good changes
          of a merge. Otherwise it is probably wasted work! Thank you
 
-DISKSTORE TODO
-==============
 
-* Fix FLUSHALL/FLUSHDB: the queue of pending reads/writes should be handled.
-* Check that 00/00 and ff/ff exist at startup, otherwise exit with error.
-* Implement sync flush option, where data is written synchronously on disk when a command is executed.
-* Implement MULTI/EXEC as transaction abstract API to diskstore.c, with transaction_start, transaction_end, and a journal to recover.
-* Stop BGSAVE thread on shutdown and any other condition where the child is killed during normal bgsave.
-* Fix RANDOMKEY to really do something interesting
-* Fix DBSIZE to really do something interesting
-* Add a DEBUG command to check if an entry is or not in memory currently
+API CHANGES
+===========
 
-* dscache.c near 236, kobj = createStringObject... we could use static obj.
+* Turn commands into variadic versions when it makes sense, that is, when
+  the variable number of arguments represent values, and there is no conflict
+  with the return value of the command.
 
 APPEND ONLY FILE
 ================
@@ -61,3 +55,15 @@ KNOWN BUGS
     or alike) too many time passes? We should prevent expires while the
     AOF is loading.
 
+DISKSTORE TODO
+==============
+
+* Fix FLUSHALL/FLUSHDB: the queue of pending reads/writes should be handled.
+* Check that 00/00 and ff/ff exist at startup, otherwise exit with error.
+* Implement sync flush option, where data is written synchronously on disk when a command is executed.
+* Implement MULTI/EXEC as transaction abstract API to diskstore.c, with transaction_start, transaction_end, and a journal to recover.
+* Stop BGSAVE thread on shutdown and any other condition where the child is killed during normal bgsave.
+* Fix RANDOMKEY to really do something interesting
+* Fix DBSIZE to really do something interesting
+* Add a DEBUG command to check if an entry is or not in memory currently
+* dscache.c near 236, kobj = createStringObject... we could use static obj.
index 0a580fa75e3268d9979e3397790a973e57e3c5c8..4e3cf74658141494810abe69a4e5997561fd1a4d 100644 (file)
@@ -943,6 +943,7 @@ void clusterCron(void) {
                 node->flags &= ~REDIS_NODE_PFAIL;
             } else if (node->flags & REDIS_NODE_FAIL && !node->numslaves) {
                 node->flags &= ~REDIS_NODE_FAIL;
+                clusterUpdateState();
             }
         } else {
             /* Timeout reached. Set the noad se possibly failing if it is
index f2e14010abd7caa69c9660857bee43c7f6cfdfa1..cd35587fe7779e41d6d38d2313f63539dd448b1c 100755 (executable)
@@ -3,6 +3,8 @@
 require 'rubygems'
 require 'redis'
 
+ClusterHashSlots = 4096
+
 def xputs(s)
     printf s
     STDOUT.flush
@@ -17,6 +19,8 @@ class ClusterNode
         end
         @host = s[0]
         @port = s[1]
+        @slots = {}
+        @dirty = false
     end
 
     def to_s
@@ -51,12 +55,55 @@ class ClusterNode
         end
     end
 
+    def add_slots(slots)
+        slots.each{|s|
+            @slots[s] = :new
+        }
+        @dirty = true
+    end
+
+    def flush_node_config
+        return if !@dirty
+        new = []
+        @slots.each{|s,val|
+            if val == :new
+                new << s
+                @slots[s] = true
+            end
+        }
+        @r.cluster("addslots",*new)
+        @dirty = false
+    end
+
+    def info
+        slots = @slots.map{|k,v| k}.reduce{|a,b|
+            a = [(a..a)] if !a.is_a?(Array)
+            if b == (a[-1].last)+1
+                a[-1] = (a[-1].first)..b
+                a
+            else
+                a << (b..b)
+            end
+        }.map{|x|
+            (x.first == x.last) ? x.first.to_s : "#{x.first}-#{x.last}"
+        }.join(",")
+        "#{self.to_s.ljust(25)} slots:#{slots}"
+    end
+    
+    def is_dirty?
+        @dirty
+    end
+
     def r
         @r
     end
 end
 
 class RedisTrib
+    def initialize
+        @nodes = []
+    end
+
     def check_arity(req_args, num_args)
         if ((req_args > 0 and num_args != req_args) ||
            (req_args < 0 and num_args < req_args.abs))
@@ -72,7 +119,52 @@ class RedisTrib
             node.connect
             node.assert_cluster
             node.assert_empty
+            @nodes << node
         }
+        puts "Performing hash slots allocation on #{@nodes.length} nodes..."
+        alloc_slots
+        show_nodes
+        yes_or_die "Can I set the above configuration?"
+        flush_nodes_config
+        puts "** Nodes configuration updated"
+        puts "Sending CLUSTER MEET messages to join the cluster"
+        join_cluster
+    end
+
+    def alloc_slots
+        slots_per_node = ClusterHashSlots/@nodes.length
+        i = 0
+        @nodes.each{|n|
+            first = i*slots_per_node
+            last = first+slots_per_node-1
+            last = ClusterHashSlots-1 if i == @nodes.length-1
+            n.add_slots first..last
+            i += 1
+        }
+    end
+
+    def flush_nodes_config
+        @nodes.each{|n|
+            n.flush_node_config
+        }
+    end
+
+    def show_nodes
+        @nodes.each{|n|
+            puts n.info
+        }
+    end
+
+    def join_cluster
+    end
+
+    def yes_or_die(msg)
+        print "#{msg} (type 'yes' to accept): "
+        STDOUT.flush
+        if !(STDIN.gets.chomp.downcase == "yes")
+            puts "Aborting..."
+            exit 1
+        end
     end
 end