The shelve module is a easy way to add persistence to your application via a DBM database. However, if you have multiple reader/writer combination you need to lock the file to prevent corruption. The shelve module itself does not provide locking because it is platform specific. If you only need Linux, this simple module provide an easy way to support locking using dynamically added methods.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #!/usr/bin/env python
import shelve, os, fcntl, new
import __builtin__
from fcntl import LOCK_SH, LOCK_EX, LOCK_UN, LOCK_NB
def _close(self):
shelve.Shelf.close(self)
fcntl.flock(self.lckfile.fileno(), LOCK_UN)
self.lckfile.close()
def open(filename, flag='c', protocol=None, writeback=False, block=True, lckfilename=None):
"""Open the sheve file, createing a lockfile at filename.lck. If
block is False then a IOError will be raised if the lock cannot
be acquired"""
if lckfilename == None:
lckfilename = filename + ".lck"
lckfile = __builtin__.open(lckfilename, 'w')
# Accquire the lock
if flag == 'r':
lockflags = LOCK_SH
else:
lockflags = LOCK_EX
if not block:
lockflags = LOCK_NB
fcntl.flock(lckfile.fileno(), lockflags)
# Open the shelf
shelf = shelve.open(filename, flag, protocol, writeback)
# Override close
shelf.close = new.instancemethod(_close, shelf, shelve.Shelf)
shelf.lckfile = lckfile
# And return it
return shelf
|