commit c518422f708e5d059f3d77e882e1da04b38d30c1
Author: Christian Fromme <kaner(a)strace.org>
Date: Sun Mar 6 14:19:27 2011 +0100
Fix #2557: Don't crash if a distributor gets disabled.
---
lib/bridgedb/Bridges.py | 16 +++++++++++++---
lib/bridgedb/Bucket.py | 12 ------------
lib/bridgedb/Main.py | 4 ++++
lib/bridgedb/Storage.py | 17 +++++++++++------
lib/bridgedb/Tests.py | 11 ++++++-----
5 files changed, 34 insertions(+), 26 deletions(-)
diff --git a/lib/bridgedb/Bridges.py b/lib/bridgedb/Bridges.py
index a06cf26..67db9af 100644
--- a/lib/bridgedb/Bridges.py
+++ b/lib/bridgedb/Bridges.py
@@ -401,6 +401,7 @@ class BridgeSplitter(BridgeHolder):
self.totalP = 0
self.pValues = []
self.rings = []
+ self.pseudoRings = []
self.statsHolders = []
def __len__(self):
@@ -423,6 +424,11 @@ class BridgeSplitter(BridgeHolder):
self.rings.append(ringname)
self.totalP += p
+ def addPseudoRing(self, ringname):
+ """Add a pseudo ring to the list of pseudo rings.
+ """
+ self.pseudoRings.append(bridgedb.Bucket.PSEUDO_DISTRI_PREFIX + ringname)
+
def addTracker(self, t):
"""Adds a statistics tracker that gets told about every bridge we see.
"""
@@ -451,11 +457,15 @@ class BridgeSplitter(BridgeHolder):
assert 0 <= pos < len(self.rings)
ringname = self.rings[pos]
- ringname = db.insertBridgeAndGetRing(bridge, ringname, time.time())
+ validRings = self.rings + self.pseudoRings
+
+ ringname = db.insertBridgeAndGetRing(bridge, ringname, time.time(),
+ validRings)
db.commit()
- # Resolve pseudo distributor ring names
- ringname = bridgedb.Bucket.getRealDistributorName(ringname)
+ # Pseudo distributors are always held in the "unallocated" ring
+ if ringname in self.pseudoRings:
+ ringname = "unallocated"
ring = self.ringsByName.get(ringname)
ring.insert(bridge)
diff --git a/lib/bridgedb/Bucket.py b/lib/bridgedb/Bucket.py
index 39edaea..1d5d753 100644
--- a/lib/bridgedb/Bucket.py
+++ b/lib/bridgedb/Bucket.py
@@ -28,18 +28,6 @@ import bridgedb.Storage
# distinguish them from real distributors?
PSEUDO_DISTRI_PREFIX = "pseudo_"
-def getRealDistributorName(distributor):
- """Return the *real* ring name for a given one. This is needed because
- with pseudo distributors, we've got strings in the database that aren't
- real distributors.
- """
-
- # If it starts with "pseudo_", its really "unallocated"
- if distributor.startswith(PSEUDO_DISTRI_PREFIX):
- distributor = "unallocated"
-
- return distributor
-
class BucketData:
"""A file bucket value class.
name - Name of the bucket (From config)
diff --git a/lib/bridgedb/Main.py b/lib/bridgedb/Main.py
index 5959a41..82181b8 100644
--- a/lib/bridgedb/Main.py
+++ b/lib/bridgedb/Main.py
@@ -276,6 +276,10 @@ def startup(cfg):
"unallocated",
cfg.RESERVED_SHARE)
+ # Add pseudo distributors to splitter
+ for p in cfg.FILE_BUCKETS.keys():
+ splitter.addPseudoRing(p)
+
# Make the parse-bridges function get re-called on SIGHUP.
def reload():
logging.info("Caught SIGHUP")
diff --git a/lib/bridgedb/Storage.py b/lib/bridgedb/Storage.py
index 2c64e83..ae48dde 100644
--- a/lib/bridgedb/Storage.py
+++ b/lib/bridgedb/Storage.py
@@ -176,9 +176,10 @@ class Database:
self._cur.close()
self._conn.close()
- def insertBridgeAndGetRing(self, bridge, setRing, seenAt):
+ def insertBridgeAndGetRing(self, bridge, setRing, seenAt, validRings,
+ defaultPool="unallocated"):
'''updates info about bridge, setting ring to setRing if none was set.
- Returns the bridge's ring.
+ Returns the bridge's validated ring.
'''
cur = self._cur
@@ -190,11 +191,15 @@ class Database:
"FROM Bridges WHERE hex_key = ?", (h,))
v = cur.fetchone()
if v is not None:
- idx, ring = v
- # Update last_seen and address.
+ i, ring = v
+ # Check if this is currently a valid ring name. If not, move back
+ # into default pool.
+ if ring not in validRings:
+ ring = defaultPool
+ # Update last_seen, address, port and (possibly) distributor.
cur.execute("UPDATE Bridges SET address = ?, or_port = ?, "
- "last_seen = ? WHERE id = ?",
- (bridge.ip, bridge.orport, timeToStr(seenAt), idx))
+ "distributor = ?, last_seen = ? WHERE id = ?",
+ (bridge.ip, bridge.orport, ring, timeToStr(seenAt), i))
return ring
else:
# Insert it.
diff --git a/lib/bridgedb/Tests.py b/lib/bridgedb/Tests.py
index f5198c4..1353658 100644
--- a/lib/bridgedb/Tests.py
+++ b/lib/bridgedb/Tests.py
@@ -156,10 +156,11 @@ class SQLStorageTests(unittest.TestCase):
b1_v2 = B("serv1", "1.2.3.5", 9099, fingerprint=k1)
b2 = B("serv2", "2.3.4.5", 9990, fingerprint=k2)
b3 = B("serv3", "2.3.4.6", 9008, fingerprint=k3)
+ validRings = ["ring1", "ring2", "ring3"]
- r = db.insertBridgeAndGetRing(b1, "ring1", t)
+ r = db.insertBridgeAndGetRing(b1, "ring1", t, validRings)
self.assertEquals(r, "ring1")
- r = db.insertBridgeAndGetRing(b1, "ring10", t+500)
+ r = db.insertBridgeAndGetRing(b1, "ring10", t+500, validRings)
self.assertEquals(r, "ring1")
cur.execute("SELECT distributor, address, or_port, first_seen, "
@@ -170,7 +171,7 @@ class SQLStorageTests(unittest.TestCase):
bridgedb.Storage.timeToStr(t),
bridgedb.Storage.timeToStr(t+500)))
- r = db.insertBridgeAndGetRing(b1_v2, "ring99", t+800)
+ r = db.insertBridgeAndGetRing(b1_v2, "ring99", t+800, validRings)
self.assertEquals(r, "ring1")
cur.execute("SELECT distributor, address, or_port, first_seen, "
"last_seen FROM Bridges WHERE hex_key = ?", (k1,))
@@ -180,8 +181,8 @@ class SQLStorageTests(unittest.TestCase):
bridgedb.Storage.timeToStr(t),
bridgedb.Storage.timeToStr(t+800)))
- db.insertBridgeAndGetRing(b2, "ring2", t)
- db.insertBridgeAndGetRing(b3, "ring3", t)
+ db.insertBridgeAndGetRing(b2, "ring2", t, validRings)
+ db.insertBridgeAndGetRing(b3, "ring3", t, validRings)
cur.execute("SELECT COUNT(distributor) FROM Bridges")
v = cur.fetchone()