0

I'm trying to implement thread- and multiprocess-safe disk cache for small application. It is only required to run on modern linux distributions, no compatibility with Windows or OS X is required.

Here is the code:

class LockedOpen(object):

    READ = 0
    WRITE = 1

    def __init__(self, filename, mode=READ, block=True):
        self._filename = filename
        if mode == LockedOpen.READ:
            self._open_mode = os.O_RDONLY
            self._lock_op = fcntl.LOCK_SH
            self._open_mode_str = 'rb'
        else:
            self._open_mode = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
            self._lock_op = fcntl.LOCK_EX
            self._open_mode_str = 'wb'

        if not block:
            self._lock_op = self._lock_op | fcntl.LOCK_NB

    def __enter__(self,):
        self._fd = os.open(self._filename, self._open_mode)
        fcntl.flock(self._fd, self._lock_op)
        self._file_obj = os.fdopen(self._fd, self._open_mode_str)
        return self._file_obj

    def __exit__(self, exc_type, exc_val, exc_tb):
        self._file_obj.flush()
        os.fdatasync(self._fd)
        fcntl.flock(self._fd, fcntl.LOCK_UN)
        self._file_obj.close()


class DiskCache(object):
    def __init__(self, dirname):
        self._dir = dirname

    def _filename_from_key(self, key):
        return os.path.join(self._dir, key)

    def put(self, key, value):
        with LockedOpen(self._filename_from_key(key), LockedOpen.WRITE) as f:
            f.write(value)

    def get(self, key):
        with LockedOpen(self._filename_from_key(key)) as f:
            return f.read()

    def delete(self, key):
        os.unlink(self._filename_from_key(key))

The question is, am I doing this right? Are there any errors/caveats/implications with this code that I should know about? Any advice regarding performance is welcome as well.

Thanks~

  • 4
    This really belongs on http://codereview.stackexchange.com/ –  Feb 06 '15 at 16:07
  • @Mike, should I repost it there or ask someone to move it? – RSSCake Feb 06 '15 at 16:13
  • Have you checked [this](http://stackoverflow.com/a/20428017/724357) first? You might not need to write it yourself. – Spencer Rathbun Feb 06 '15 at 16:16
  • 3
    have you tested the code? does it run the way you intend it to? And most importantly, is this your code? These are good indicators of whether or not it belongs on CodeReview – Malachi Feb 06 '15 at 16:21
  • @Spencer Rathbun, for such a small app solutions like dogpile.cache seem to be an overkill. A want something small, fast and simple at the expense of portability – RSSCake Feb 06 '15 at 16:26
  • @Malachi, this is my code, although I suspect i'm inventing a bicycle here :) no tests yet, and I haven't tried to use it yet. – RSSCake Feb 06 '15 at 16:34
  • if you try to use it and it works then it would be on-topic for CodeReview – Malachi Feb 06 '15 at 16:47

0 Answers0