How to implement retrying a lock tidily in Python?

Chris Torek nospam at torek.net
Sun Oct 17 19:52:34 CEST 2010


In article <4imro7-ds6.ln1 at chris.zbmc.eu>,  <tinnews at isbd.co.uk> wrote:
>I'm writing some code that writes to a mbox file and want to retry
>locking the mbox file a few times before giving up. ...

>    dest = mailbox.mbox(mbName, factory=None)
>    for tries in xrange(3):
>        try:
>            dest.lock()
>            #
>            #
>            # Do some stuff to the mbox file
>            #
>            dest.unlock()
>            break       # done what we need, carry on
>
>        except mailbox.ExternalClashError:
>            log("Destination locked, try " + str(tries))
>            time.sleep(1)
>            # and try again
>
>... but this doesn't really work 'nicely' because the break after
>dest.unlock() takes me to the same place as running out of the number
>of tries in the for loop.

Seems to me the "right place" for this is a little wrapper lock as
it were:

    def retried_lock(max_attempts=3):
        for tries in xrange(max_attempts):
            try:
                self.lock()
                return # got the lock
            except mailbox.ExternalClashError:
                log and sleep here
        raise mailbox.ExternalClashError # or whatever

and now instead of dest.lock() you just do a dest.retried_lock().

Plumbing (including fitting this in as a context manager so
that you can just do "with dest" or some such) is left as an
exercise, :-)
-- 
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W)  +1 801 277 2603
email: gmail (figure it out)      http://web.torek.net/torek/index.html



More information about the Python-list mailing list