Search code examples
pythonflaskzodb

LockError using flask-zodb


I have a problem using flask-zodb in a simple Flask app deployed with mod_wsgi. Every time I try to use the DB for example setting defaults:

from flaskext.zodb import zodb, List

db = ZODB(app)
app.config.from_pyfile('settings.py') # here I have defined ZODB_STORAGE = "/home/username/webapps/myapp/htdocs/Data.fs"

@app.before_request
def set_db_defaults():
   if 'entries' not in db:
       db['entries'] = List()

or in a view like:

@app.route('/add', methods=['POST'])
def add_entry():
   db['entries'].append(request.form)
   flash('New entry was successfully posted')
   return redirect(url_for('show_entries'))

I got the following error:

[Sat May 19 16:52:30 2012] [error] [client 127.0.0.1]
self._lock_file = LockFile(file_name + '.lock')
[Sat May 19 16:52:30 2012] [error] [client 127.0.0.1]   File
"/home/userame/.virtualenvs/myapp/lib/python2.7/site-packages/zc/lockfile/__init__.py",
line 76, in __init__
[Sat May 19 16:52:30 2012] [error] [client 127.0.0.1]     _lock_file(fp)
[Sat May 19 16:52:30 2012] [error] [client 127.0.0.1]   File
"/home/username/.virtualenvs/myapp/lib/python2.7/site-packages/zc/lockfile/__init__.py",
line 59, in _lock_file
[Sat May 19 16:52:30 2012] [error] [client 127.0.0.1]     raise
LockError("Couldn't lock %r" % file.name)
[Sat May 19 16:52:30 2012] [error] [client 127.0.0.1] LockError:
Couldn't lock '/home/username/webapps/myapp/htdocs/Data.fs.lock'

The application works fine in the development enviroment and I do not think there's a premission problem since I tried to set:

ZODB_STORAGE = "/tmp"

And the same exception is raised. I can't understand why this happens and how to avoid this kind of error. Any ideas?


Solution

  • You are trying to open the ZODB from multiple processes; presumably in development you only use one WSGI process. This is basically a dupe of zc.lockfile.LockError in ZODB.

    Your options are:

    1. Limit your production environment to only one process.

    2. Use ZEO, see the referenced question; the zodburi equivalent is zeo://localhost:9100.

    3. Use RelStorage. You can use the ZConfig URI scheme to connect up, provided the RelStorage egg is available. This is documented in the RelStorage documentation under the old repoze.zodbconn name.