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