CGIs and file exclusion

Michele Simionato michele.simionato at gmail.com
Fri Nov 5 23:49:50 EST 2004


fuzzyman at gmail.com (Michael Foord) wrote in message news:<6f402501.0411050228.aea8068 at posting.google.com>...
> A simple solution that doesn't scale well is to create a file when the
> access starts. You can check if the file exists and pause until the
> other process deletes it - with a timeout in case the file gets keft
> there due to an error.
> 
> Obviously not an industrial strength solution, but it does work...
> 
> import time
> import os
> 
> def sleep(thelockfile, sleepcycle=0.01, MAXCOUNT=200):
>     """Sleep until the lockfile has been removed or a certain number
> of cycles have gone.
>     Defaults to a max 2 second delay.
>     """
>     counter = 0
>     while os.path.exists(thelockfile):
>         time.sleep(sleepcycle)
>         counter += 1
>         if counter > MAXCOUNT: break
>         
> def createlock(thelockfile):
>     """Creates a lockfile from the path supplied."""
>     open(thelockfile, 'w').close()
>     
> def releaselock(thelockfile):
>     """Deletes the lockfile."""
>     if os.path.isfile(thelockfile):
>         os.remove(thelockfile)
> 
> The sleep function waits until the specified file dissapears - or it
> times out.

I tried essentially the same solution in my experiments, but I was
unhappy
with it: it seems to work 99% of times, but occasionally you get
strange
things (for instance once I got "File not found" when trying to remove
the lockfile, evidently it was already removed by another process;
other
times I got different strange errors). The issue is that it is very 
difficult to reproduce the problems, hence to fix them. Maybe
Diez B. Roggisch is right and a real database server is the simplest 
solution. However my first attempt with ZEO didn't worked either:

$ cat zeoclient.py
import ZODB, ZEO 
from ZEO.ClientStorage import ClientStorage

def openzeo(host, port):
    db = ZODB.DB(ClientStorage((host, port)))
    conn = db.open()
    return db, conn, conn.root()

def store():
    # I have a ZEO instance running on port 9999 
    print "Opening the db ..."
    db, conn, root = openzeo("localhost", 9999)
    print "Storing something ..."
    root["somekey"] = "somedata"
    get_transaction().commit()
    print "Closing the db ..."
    conn.close(); db.close()

if __name__ == "__main__":
    store()

$ echo Makefile
default:
	python zeoclient.py& 
	python zeoclient.py

$ make
python zeoclient.py&
python zeoclient.py
Opening the db ...
Opening the db ...

Storing something ...
Storing something ...
Closing the db ...
Traceback (most recent call last):
  File "zeoclient.py", line 20, in ?
    store()
  File "zeoclient.py", line 15, in store
    get_transaction().commit()
  File "/usr/share/partecs/zope/lib/python/ZODB/Transaction.py", line
247, in commit
~/pt/python/zopexplore $
~/pt/python/zopexplore $     vote(self)
  File "/usr/share/partecs/zope/lib/python/ZODB/Connection.py", line
699, in tpc_vote
    s = vote(transaction)
  File "/opt/zope/lib/python/ZEO/ClientStorage.py", line 841, in
tpc_vote
    return self._check_serials()
  File "/opt/zope/lib/python/ZEO/ClientStorage.py", line 825, in
_check_serials
    raise s
ZODB.POSException.ConflictError: database conflict error (oid
0000000000000000, serial was 035900d31b7fedaa, now 035900d2f6cd8799)

(it works with a single process instead).

Maybe I misunderstood how ZEO is intended to be used, as usual it is
difficult to found the relevant documentation :-( Maybe I should ask
on another list ...


  Michele Simionato



More information about the Python-list mailing list