mirror of
https://github.com/bugsink/bugsink.git
synced 2025-12-30 09:50:11 -06:00
67 lines
2.3 KiB
Python
67 lines
2.3 KiB
Python
# A super-simple utility to run the WSGI application using the built-in WSGI server. The usefulness of this script is
|
|
# precisely because there is _no_ special handling of SIGINT. This means that SIGINT can be used to get a traceback
|
|
# from the application as it was when interrupted. This is useful to answer the question "why is this application
|
|
# stuck?"
|
|
|
|
# This version is for SQLite. sqlite3 does not support interrupts (i.e. it does not check with Python's signal handler),
|
|
# so we need to do it ourselves. In this case we attempt that by setting a progress handler that checks for a global
|
|
# variable that is set by the signal handler.
|
|
|
|
# This solution prints a stack trace, but then hangs for reasons I don't understand.
|
|
# (a version without a signal handler (implicit KeyboardInterrupt) works just as well / just as poorly)
|
|
|
|
import sys
|
|
import signal
|
|
|
|
from wsgiref import simple_server
|
|
from bugsink.wsgi import application
|
|
from django.db.backends.sqlite3.base import DatabaseWrapper
|
|
|
|
|
|
interrupted = False
|
|
|
|
|
|
def handle_sigint(signal, frame):
|
|
global interrupted
|
|
interrupted = True
|
|
|
|
|
|
signal.signal(signal.SIGINT, handle_sigint)
|
|
|
|
|
|
def stop_when_interrupted():
|
|
global interrupted
|
|
if interrupted:
|
|
interrupted = False
|
|
return -1
|
|
return 0
|
|
|
|
|
|
def get_new_connection_with_check(self, conn_params):
|
|
conn = original_get_new_connection(self, conn_params)
|
|
# this is the first thing I tried; it works just fine, but so does any old python code, because any old python code
|
|
# has PyErr_CheckSignals in its execution path.
|
|
# conn.set_progress_handler(ctypes.pythonapi.PyErr_CheckSignals, 50)
|
|
conn.set_progress_handler(stop_when_interrupted, 50)
|
|
# conn.set_progress_handler(lambda: None, 50) # the version without the signal handler (assumes signal.siganl is
|
|
# not done, and the lambda is a moment for the regular Python signal handler, which raises keyboardInterrupt, to
|
|
# run)
|
|
return conn
|
|
|
|
|
|
original_get_new_connection = DatabaseWrapper.get_new_connection
|
|
DatabaseWrapper.get_new_connection = get_new_connection_with_check
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# the actual server:
|
|
if len(sys.argv) < 2:
|
|
host = "127.0.0.1"
|
|
port = 8000
|
|
else:
|
|
host = sys.argv[1].split(":")[0]
|
|
port = int(sys.argv[1].split(":")[1])
|
|
|
|
httpd = simple_server.make_server(host, port, application)
|
|
httpd.serve_forever()
|