summary refs log tree commit diff
diff options
context:
space:
mode:
authorErik Johnston <erik@matrix.org>2019-08-20 11:49:44 +0100
committerErik Johnston <erik@matrix.org>2019-08-20 12:36:11 +0100
commit1f9df1cc7ba7027aef3a38d01909a928ecf2a8c5 (patch)
tree86ca74c2442826f692eaf789ad8e5e40d55b466c
parentRemove test debugs (diff)
downloadsynapse-1f9df1cc7ba7027aef3a38d01909a928ecf2a8c5.tar.xz
Fixup _sort_server_list to be slightly more efficient
Also document that we are using the algorithm described in RFC2782 and
ensure we handle zero weight correctly.
-rw-r--r--synapse/http/federation/srv_resolver.py13
1 files changed, 11 insertions, 2 deletions
diff --git a/synapse/http/federation/srv_resolver.py b/synapse/http/federation/srv_resolver.py
index bbda0a23f4..110b112e85 100644
--- a/synapse/http/federation/srv_resolver.py
+++ b/synapse/http/federation/srv_resolver.py
@@ -94,10 +94,18 @@ def _sort_server_list(server_list):
 
     results = []
     for priority in sorted(priority_map):
-        servers = priority_map.pop(priority)
+        servers = priority_map[priority]
 
+        # This algorithms follows the algorithm described in RFC2782.
+        #
+        # N.B. Weights can be zero, which means that you should pick that server
+        # last *or* that its the only server in this priority.
+
+        # We sort to ensure zero weighted items are first.
+        servers.sort(key=lambda s: s.weight)
+
+        total_weight = sum(s.weight for s in servers)
         while servers:
-            total_weight = sum(s.weight for s in servers)
             target_weight = random.randint(0, total_weight)
 
             for s in servers:
@@ -108,6 +116,7 @@ def _sort_server_list(server_list):
 
             results.append(s)
             servers.remove(s)
+            total_weight -= s.weight
 
     return results