Welcome, guest | Sign In | My Account | Store | Cart

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.

Python, 36 lines
 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