Commit 5c014e87 by Gabriel Falcao

trying to handle signals better

parent 5c51567e
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import os import os
import sys import sys
import signal
from optparse import make_option from optparse import make_option
from django.conf import settings from django.conf import settings
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
...@@ -54,6 +55,7 @@ class Command(BaseCommand): ...@@ -54,6 +55,7 @@ class Command(BaseCommand):
help='Comma separated list of scenarios to run'), help='Comma separated list of scenarios to run'),
) )
def stopserver(self, failed=False): def stopserver(self, failed=False):
server.stop(fail=failed)
raise SystemExit(int(failed)) raise SystemExit(int(failed))
def get_paths(self, args, apps_to_run, apps_to_avoid): def get_paths(self, args, apps_to_run, apps_to_avoid):
...@@ -69,7 +71,17 @@ class Command(BaseCommand): ...@@ -69,7 +71,17 @@ class Command(BaseCommand):
return paths return paths
def handle_control_c(self, signum, frame):
print "oops, aborting..."
server.stop(fail=True)
print 'harvest aborted, no crops for this spring :('
sys.exit(2)
def handle(self, *args, **options): def handle(self, *args, **options):
signal.signal(signal.SIGABRT, self.handle_control_c)
signal.signal(signal.SIGTERM, self.handle_control_c)
signal.signal(signal.SIGINT, self.handle_control_c)
setup_test_environment() setup_test_environment()
settings.DEBUG = options.get('debug', False) settings.DEBUG = options.get('debug', False)
......
...@@ -63,6 +63,10 @@ class MutedRequestHandler(WSGIRequestHandler): ...@@ -63,6 +63,10 @@ class MutedRequestHandler(WSGIRequestHandler):
def handle(self): def handle(self):
"""Handle a single HTTP request""" """Handle a single HTTP request"""
global keep_running
if not keep_running:
return
self.raw_requestline = self.rfile.readline() self.raw_requestline = self.rfile.readline()
if not self.parse_request(): # An error code has been sent, just exit if not self.parse_request(): # An error code has been sent, just exit
return return
...@@ -73,11 +77,18 @@ class MutedRequestHandler(WSGIRequestHandler): ...@@ -73,11 +77,18 @@ class MutedRequestHandler(WSGIRequestHandler):
self.dev_null, self.dev_null,
self.get_environ() self.get_environ()
) )
if not keep_running:
return
handler.request_handler = self # backpointer for logging handler.request_handler = self # backpointer for logging
handler.run(self.server.get_app()) handler.run(self.server.get_app())
class LettuceServerHandler(ServerHandler): class LettuceServerHandler(ServerHandler):
def finish_response(self): def finish_response(self):
global keep_running
if not keep_running:
return
try: try:
ServerHandler.finish_response(self) ServerHandler.finish_response(self)
...@@ -109,11 +120,13 @@ class ThreadedServer(threading.Thread): ...@@ -109,11 +120,13 @@ class ThreadedServer(threading.Thread):
def wait(self): def wait(self):
address = ThreadedServer.get_real_address(self.address) address = ThreadedServer.get_real_address(self.address)
while True: while keep_running:
time.sleep(0.1) time.sleep(1)
http = httplib.HTTPConnection(address, self.port) http = httplib.HTTPConnection(address, self.port)
try: try:
http.request("GET", "/") http.request("GET", "/")
self.lock.release()
except socket.error: except socket.error:
http.close() http.close()
continue continue
...@@ -122,6 +135,8 @@ class ThreadedServer(threading.Thread): ...@@ -122,6 +135,8 @@ class ThreadedServer(threading.Thread):
self.lock.acquire() self.lock.acquire()
def run(self): def run(self):
global keep_running
self.lock.acquire() self.lock.acquire()
pidfile = os.path.join(tempfile.gettempdir(), 'lettuce-django.pid') pidfile = os.path.join(tempfile.gettempdir(), 'lettuce-django.pid')
if os.path.exists(pidfile): if os.path.exists(pidfile):
...@@ -141,9 +156,11 @@ class ThreadedServer(threading.Thread): ...@@ -141,9 +156,11 @@ class ThreadedServer(threading.Thread):
max_port = 65535 max_port = 65535
connector = socket.socket(socket.AF_INET, socket.SOCK_STREAM) connector = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while not bound or self.port < max_port: while keep_running and (not bound or self.port < max_port):
time.sleep(1)
try: try:
connector.connect((self.address, self.port)) connector.connect((self.address, self.port))
self.port += 1 self.port += 1
except socket.error: except socket.error:
...@@ -169,16 +186,28 @@ class ThreadedServer(threading.Thread): ...@@ -169,16 +186,28 @@ class ThreadedServer(threading.Thread):
if 'django.contrib.admin' in settings.INSTALLED_APPS: if 'django.contrib.admin' in settings.INSTALLED_APPS:
admin_media_path = '' admin_media_path = ''
handler = AdminMediaHandler(handler, admin_media_path) handler = AdminMediaHandler(handler, admin_media_path)
print "Preparing to server django's admin site static files..." print "Preparing to serve django's admin site static files..."
httpd.set_app(handler) httpd.set_app(handler)
global keep_running
while keep_running: while keep_running:
time.sleep(1)
call_hook('before', 'handle_request', httpd, self) call_hook('before', 'handle_request', httpd, self)
# timeout http://bugs.python.org/issue1167930 between big
# amounts of CPU usage
time.sleep(1) # part 1
httpd.handle_request() httpd.handle_request()
time.sleep(1) # part 2
call_hook('after', 'handle_request', httpd, self) call_hook('after', 'handle_request', httpd, self)
if self.lock.locked(): if self.lock.locked():
time.sleep(1)
self.lock.release() self.lock.release()
class Server(object): class Server(object):
...@@ -202,6 +231,9 @@ class Server(object): ...@@ -202,6 +231,9 @@ class Server(object):
print "Django's builtin server is running at %s:%d" % addrport print "Django's builtin server is running at %s:%d" % addrport
def stop(self, fail=False): def stop(self, fail=False):
global keep_running
keep_running = False
http = httplib.HTTPConnection(self.address, self.port) http = httplib.HTTPConnection(self.address, self.port)
try: try:
http.request("DELETE", "/") http.request("DELETE", "/")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment