[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[minion-cvs] Change the rule for which descriptors get included in t...
Update of /home/minion/cvsroot/src/minion/lib/mixminion/directory
In directory moria.mit.edu:/tmp/cvs-serv31412/lib/mixminion/directory
Modified Files:
ServerList.py
Log Message:
Change the rule for which descriptors get included in the directory.
The old rule was: If A and B supercede C over all time, don't include C.
The new rule is: If A and B supercede C _over the interveral of time
for which the directory is generated_, don't included C.
This way, if the directory gets C (valid Jan-May), and then gets a
more recently published A (valid Jan-Feb) it won't include "C" when
generating a directory for Jan.
(whew!)
Index: ServerList.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/directory/ServerList.py,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- ServerList.py 30 May 2003 07:36:28 -0000 1.27
+++ ServerList.py 2 Jun 2003 20:55:23 -0000 1.28
@@ -98,7 +98,7 @@
idCache = mixminion.directory.Directory.IDCache(
os.path.join(baseDir, "xx_idcache"))
self.idCache = idCache
-
+
self.serverIDDir = os.path.join(self.baseDir, "server-ids")
self.serverDir = os.path.join(self.baseDir, "servers")
self.rejectDir = os.path.join(self.baseDir, "reject")
@@ -114,7 +114,7 @@
createPrivateDir(self.archiveDir)
createPrivateDir(self.dirArchiveDir)
self.rescan()
-
+
def isServerKnown(self, server):
"""Return true iff the current server descriptor is known. Raises
MixError if we have a server descriptor with this name, but
@@ -141,7 +141,7 @@
LOG.warn("Server %s already known", nickname)
except mixminion.directory.MismatchedID:
raise MixFatalError("Mismatched ID for server %s", nickname)
-
+
LOG.info("Learning identity for new server %s", nickname)
self.idCache.insertServer(server)
writePickled(os.path.join(self.serverIDDir,
@@ -225,7 +225,7 @@
LOG.info(" (%s servers removed)", len(servers))
finally:
self._unlock()
-
+
def generateDirectory(self,
startAt, endAt, extraTime,
identityKey,
@@ -233,7 +233,7 @@
badServers=()):
"""Generate and sign a new directory, to be effective from <startAt>
through <endAt>. It includes all servers that are valid at
- any time between <startAt> and <endAt>+>extraTime>. The directory
+ any time between <startAt> and <endAt>+<extraTime>. The directory
is signed with <identityKey> """
try:
self._lock()
@@ -242,14 +242,43 @@
publicationTime = time.time()
if previousMidnight(startAt) >= previousMidnight(endAt):
raise MixError("Validity range does not contain a full day.")
- included = []
+
+ # First, sort all servers by nickname.
+ includedByNickname = {}
for fn, s in self.servers.items():
- if not s.isValidAtPartOf(startAt, endAt+extraTime):
- continue
- nickname = s.getNickname()
- validAfter = s['Server']['Valid-After']
- included.append((nickname, validAfter, fn))
+ nickname = s.getNickname().lower()
+ includedByNickname.setdefault(nickname, []).append((s, fn))
+
+ # Second, find all servers that are valid for part of the period,
+ # and that aren't superceded for the whole period.
+ timeRange = IntervalSet([(previousMidnight(startAt),
+ endAt+extraTime)])
+ for nickname, ss in includedByNickname.items():
+ # We prefer the most-recently-published descriptor. If two
+ # are published at the same time, we prefer the one that
+ # expires last.
+ ss = [ (s['Server']['Published'],
+ s['Server']['Valid-Until'],
+ s, fn) for s,fn in ss]
+ ss.sort()
+ ss.reverse()
+ uncovered = timeRange.copy()
+ included = []
+ for _, _, s, fn in ss:
+ valid = s.getIntervalSet()
+ if (uncovered * valid):
+ included.append((s, fn))
+ uncovered -= valid
+ includedByNickname[nickname] = included
+
+ # Now sort the remaining servers by nickname, then by valid-after.
+ included = []
+ for ss in includedByNickname.values():
+ for s,fn in ss:
+ nickname = s.getNickname()
+ validAfter = s['Server']['Valid-After']
+ included.append((nickname, validAfter, fn))
included.sort()
# FFFF We should probably not do all of this in RAM, but
@@ -317,7 +346,7 @@
f.close()
finally:
self._unlock()
-
+
def getDirectoryFilename(self):
"""Return the filename of the most recently generated directory"""
return os.path.join(self.baseDir, "directory")
@@ -363,7 +392,7 @@
self.__buildNicknameMap()
finally:
self._unlock()
-
+
def rescan(self):
"""Reconstruct this ServerList object's internal state."""
try:
@@ -416,7 +445,7 @@
self.__buildNicknameMap()
finally:
self._unlock()
-
+
def __buildNicknameMap(self):
"""Helper method. Regenerate self.serversByNickname from
self.servers