Browse Source

Restructure WSGI app to regenerate error on each call, if needed

This way, errors like "database already locked" can be fixed and the
page reloaded, without needing to restart Apache.
tags/nilmdb-1.4.4
Jim Paris 11 years ago
parent
commit
dd5fc806e5
1 changed files with 31 additions and 29 deletions
  1. +31
    -29
      nilmdb/server/server.py

+ 31
- 29
nilmdb/server/server.py View File

@@ -538,13 +538,8 @@ class Server(object):
else: else:
cherrypy.server.shutdown_timeout = 5 cherrypy.server.shutdown_timeout = 5


def get_application(self): # pragma: no cover
"""Return a WSGI application object"""
def app(environ, start_response):
if environ['wsgi.multiprocess']:
raise Exception("can't function in a multi-process environment")
return cherrypy.tree(environ, start_response)
return app
# Set up the WSGI application pointer for external programs
self.wsgi_application = cherrypy.tree


def json_error_page(self, status, message, traceback, version): def json_error_page(self, status, message, traceback, version):
"""Return a custom error page in JSON so the client can parse it""" """Return a custom error page in JSON so the client can parse it"""
@@ -623,28 +618,35 @@ def wsgi_application(dbpath, basepath): # pragma: no cover
is the same as the first argument to Apache's WSGIScriptAlias is the same as the first argument to Apache's WSGIScriptAlias
directive. directive.
""" """
try:
db = nilmdb.utils.serializer_proxy(nilmdb.server.NilmDB)(dbpath)
server = nilmdb.server.Server(db, embedded = True,
basepath = basepath.rstrip('/'))
application = server.get_application()
except Exception:
# If we can't make the DB or server, serve up the exception text
# with a mini WSGI app.
output = sprintf("Initializing database at path '%s' failed:\n\n",
dbpath)
output += traceback.format_exc()
try:
import pwd
import grp
output += sprintf("\nRunning as: uid=%d (%s), gid=%d (%s)\n",
os.getuid(), pwd.getpwuid(os.getuid())[0],
os.getgid(), grp.getgrgid(os.getgid())[0])
except ImportError:
pass
def application(environ, start_response):
server = [None]
def application(environ, start_response):
if server[0] is None:
# Try to start the server
try:
db = nilmdb.utils.serializer_proxy(nilmdb.server.NilmDB)(dbpath)
server[0] = nilmdb.server.Server(
db, embedded = True,
basepath = basepath.rstrip('/'))
except Exception:
# Build an error message on failure
err = sprintf("Initializing database at path '%s' failed:\n\n",
dbpath)
err += traceback.format_exc()
try:
import pwd
import grp
err += sprintf("\nRunning as: uid=%d (%s), gid=%d (%s)\n",
os.getuid(), pwd.getpwuid(os.getuid())[0],
os.getgid(), grp.getgrgid(os.getgid())[0])
except ImportError:
pass
if server[0] is None:
# Serve up the error with our own mini WSGI app.
headers = [ ('Content-type', 'text/plain'), headers = [ ('Content-type', 'text/plain'),
('Content-length', str(len(output))) ]
('Content-length', str(len(err))) ]
start_response("500 Internal Server Error", headers) start_response("500 Internal Server Error", headers)
return [output]
return [err]

# Call the normal application
return server[0].wsgi_application(environ, start_response)
return application return application

Loading…
Cancel
Save