KCC: rewrite random intrasite connection addition for clarity
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Thu, 12 Mar 2015 04:08:55 +0000 (17:08 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 29 May 2015 04:58:24 +0000 (06:58 +0200)
And add debug messages. No change in results though.

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/scripting/bin/samba_kcc

index 963040e1a8eeef29c927d637bc09ce8c2b1028cf..5ecc20d924dc0b0be5370a5086702b52af473003 100755 (executable)
@@ -2108,7 +2108,6 @@ class KCC(object):
         r_list.append(l_of_x)
 
         r_list.sort(sort_replica_by_dsa_guid)
-        DEBUG_GREEN([x.rep_dsa_dnstr for x in r_list])
 
         r_len = len(r_list)
 
@@ -2144,7 +2143,6 @@ class KCC(object):
         if not r_list[0].is_partial() or r_list[r_len-1].is_partial():
             graph_list[r_len-1].add_edge_from(r_list[0].rep_dsa_dnstr)
 
-
         if opts.verify or opts.dot_files:
             dot_edges = []
             dot_vertices = set()
@@ -2174,10 +2172,8 @@ class KCC(object):
             i = i + 1
         DEBUG([x.rep_dsa_dnstr for x in r_list])
         DEBUG_YELLOW([x.dsa_dnstr for x in graph_list])
-        i = 0
-        while i < r_len:
-            tnode = graph_list[i]
 
+        for tnode in graph_list:
             # To optimize replication latency in sites with many NC replicas, the
             # KCC adds new edges directed to ri to bring the total edges to n+2,
             # where the NC replica rk of R from which the edge is directed
@@ -2190,36 +2186,28 @@ class KCC(object):
             # in |R| (i.e. if n is zero then at least replicas from two other graph
             # nodes may direct edges to us).
             if r_len >= 3:
-                # pick a random index
-                findex = rindex = random.randint(0, r_len-1)
-
-                # while this node doesn't have sufficient edges
-                while not tnode.has_sufficient_edges():
-                    # If this edge can be successfully added (i.e. not
-                    # the same node and edge doesn't already exist) then
-                    # select a new random index for the next round
-                    if tnode.add_edge_from(graph_list[rindex].dsa_dnstr):
-                        findex = rindex = random.randint(0, r_len-1)
-                    else:
-                        # Otherwise continue looking against each node
-                        # after the random selection
-                        rindex = rindex + 1
-                        if rindex >= r_len:
-                            rindex = 0
+                candidates = [x for x in graph_list if (x is not tnode and
+                                                        x.dsa_dnstr not in tnode.edge_from)]
 
-                        if rindex == findex:
-                            logger.error("Unable to satisfy max edge criteria!")
-                            break
+                DEBUG_BLUE("looking for random link for %s. r_len %d, graph len %d candidates %d"
+                           % (tnode.dsa_dnstr, r_len, len(graph_list), len(candidates)))
+
+                DEBUG("candidates %s" % [x.dsa_dnstr for x in candidates])
+
+                while candidates and not tnode.has_sufficient_edges():
+                    other = random.choice(candidates)
+                    if not tnode.add_edge_from(other):
+                        DEBUG_RED("could not add remote %s" % other.dsa_dstr)
+                    candidates.remove(other)
 
             # Print the graph node in debug mode
             logger.debug("%s" % tnode)
 
             # For each edge directed to the local DC, ensure a nTDSConnection
             # points to us that satisfies the KCC criteria
-            if graph_list[i].dsa_dnstr == dc_local.dsa_dnstr:
-                graph_list[i].add_connections_from_edges(dc_local)
+            if tnode.dsa_dnstr == dc_local.dsa_dnstr:
+                tnode.add_connections_from_edges(dc_local)
 
-            i = i + 1
 
         if opts.verify or opts.dot_files:
             dot_edges = []
@@ -2297,7 +2285,7 @@ class KCC(object):
                 if connect.to_be_modified:
                     logger.info("TO BE MODIFIED:\n%s" % connect)
                 if connect.to_be_added:
-                    logger.info("TO BE ADDED:\n%s" % connect)
+                    DEBUG_GREEN("TO BE ADDED:\n%s" % connect)
 
             mydsa.commit_connections(self.samdb, ro=True)
         else: