summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbwarsaw2001-04-02 06:01:49 +0000
committerbwarsaw2001-04-02 06:01:49 +0000
commit34f6cd590b41a5247b0c1bc7ba990a7e286ee04a (patch)
treef9c038bba45eebd5ac4d9a17a2b67ac5ac2a1f86
parent7b46e58984efd02d53fd74056bb90e9a7daab8ff (diff)
downloadmailman-34f6cd590b41a5247b0c1bc7ba990a7e286ee04a.tar.gz
mailman-34f6cd590b41a5247b0c1bc7ba990a7e286ee04a.tar.zst
mailman-34f6cd590b41a5247b0c1bc7ba990a7e286ee04a.zip
Changes to the new pending.db file format:
- Entry eviction times are stored as a sub-dictionary under a separate key called `evictions'. This leaves the cookie data as whatever was given to the new() function. The keys of the eviction dictionary are the cookies and the values are the time at which the entry should be removed. - Another new key `version' for future backwards compatibility <wink>. - Each entry for the cookie should have a op key as its first element, which currently should be either Pending.SUBSCRIPTION or Pending.UNSUBSCRIPTION. new(): Make sure the `evictions' dictionary is present. confirm(): Don't strip off the last element of the tuple. _load(): If there's no pending.db file, return a dictionary containing an empty `evictions' sub-dictionary. _save(): Check the eviction times in the `evictions' sub-dictionary. Also, add the schema `version' entry. _update(): Fix the conversion from pending_subscriptions.db to pending.db file format so that SUBSCRIPTION entries include a default language. Also move the eviction times (which in the old format are the time the request was made) to the `evictions' sub-dictionary and add the PENDING_REQUEST_LIFE value.
-rw-r--r--Mailman/Pending.py44
1 files changed, 37 insertions, 7 deletions
diff --git a/Mailman/Pending.py b/Mailman/Pending.py
index 96c74511f..44b7c94e7 100644
--- a/Mailman/Pending.py
+++ b/Mailman/Pending.py
@@ -35,10 +35,16 @@ from Mailman import LockFile
DBFILE = os.path.join(mm_cfg.DATA_DIR, 'pending.db')
LOCKFILE = os.path.join(mm_cfg.LOCK_DIR, 'pending.lock')
+# Types of pending records
+SUBSCRIPTION = 'S'
+UNSUBSCRIPTION = 'U'
+
def new(*content):
"""Create a new entry in the pending database, returning cookie for it."""
+ # It's a programming error if this assertion fails!
+ assert content[:1] in ((SUBSCRIPTION,), (UNSUBSCRIPTION,))
# Acquire the pending database lock, letting TimeOutError percolate up.
lock = LockFile.LockFile(LOCKFILE)
lock.lock(timeout=30)
@@ -55,7 +61,9 @@ def new(*content):
break
# Store the content, plus the time in the future when this entry will
# be evicted from the database, due to staleness.
- db[cookie] = content + (now + mm_cfg.PENDING_REQUEST_LIFE,)
+ db[cookie] = content
+ evictions = db.setdefault('evictions', {})
+ evictions[cookie] = now + mm_cfg.PENDING_REQUEST_LIFE
_save(db)
return cookie
finally:
@@ -78,8 +86,7 @@ def confirm(cookie):
# Remove the entry from the database
del db[cookie]
_save(db)
- # Strip off the timestamp and return the data
- return content[:-1]
+ return content
finally:
lock.unlock()
@@ -93,17 +100,22 @@ def _load():
except IOError, e:
if e.errno <> errno.ENOENT: raise
# No database yet, so initialize a fresh one
- return {}
+ return {'evictions': {}}
def _save(db):
# Lock must be acquired.
+ evictions = db['evictions']
now = time.time()
for cookie, data in db.items():
- timestamp = data[-1]
+ if cookie in ('evictions', 'version'):
+ continue
+ timestamp = evictions[cookie]
if now > timestamp:
# The entry is stale, so remove it.
del db[cookie]
+ del evictions[cookie]
+ db['version'] = mm_cfg.PENDING_FILE_SCHEMA_VERSION
omask = os.umask(007)
try:
fp = open(DBFILE, 'w')
@@ -115,7 +127,7 @@ def _save(db):
def _update(olddb):
- # Update an old pending database to the new database
+ # Update an old pending_subscriptions.db database to the new format
lock = LockFile.LockFile(LOCKFILE)
lock.lock(timeout=30)
try:
@@ -123,7 +135,25 @@ def _update(olddb):
if olddb.has_key('lastculltime'):
del olddb['lastculltime']
db = _load()
- db.update(olddb)
+ evictions = db.setdefault('evictions', {})
+ for cookie, data in olddb.items():
+ # The cookies used to be kept as a 6 digit integer. We now keep
+ # the cookies as a string (sha in our case, but it doesn't matter
+ # for cookie matching).
+ cookie = str(cookie)
+ # The old format kept the content as a tuple and tacked the
+ # timestamp on as the last element of the tuple. We keep the
+ # timestamps separate, but require the prepending of a record type
+ # indicator. We know that the only things that were kept in the
+ # old format were subscription requests. Also, the old request
+ # format didn't have the subscription language. Best we can do
+ # here is use the server default.
+ db[cookie] = (SUBSCRIPTION,) + data[:-1] + \
+ (mm_cfg.DEFAULT_SERVER_LANGUAGE,)
+ # The old database format kept the timestamp as the time the
+ # request was made. The new format keeps it as the time the
+ # request should be evicted.
+ evictions[cookie] = data[-1] + mm_cfg.PENDING_REQUEST_LIFE
_save(db)
finally:
lock.unlock()