Make web.py applications stoppable in stand-alone mode #122

Closed
wants to merge 1 commit into
from
View
@@ -1,5 +1,6 @@
import webtest
import time
+import threading
import web
import urllib
@@ -324,5 +325,23 @@ def f(script_name=""):
self.assertEquals(f(''), 'foo=bar; Path=/')
self.assertEquals(f('/admin'), 'foo=bar; Path=/admin/')
+ def test_stopsimpleserver(self):
+ urls = (
+ '/', 'index',
+ )
+ class index:
+ def GET(self):
+ pass
+ app = web.application(urls, locals())
+ thread = threading.Thread(target=app.run)
+
+ thread.start()
+ time.sleep(1)
+ self.assertTrue(thread.is_alive())
+
+ app.stop()
+ thread.join(timeout=1)
+ self.assertFalse(thread.is_alive())
+
if __name__ == '__main__':
webtest.main()
View
@@ -48,6 +48,7 @@ def __init__(self, mapping=(), fvars={}, autoreload=None):
self.add_processor(loadhook(self._load))
self.add_processor(unloadhook(self._unload))
+ self._simpleserver = None
if autoreload:
def main_module_name():
@@ -308,7 +309,12 @@ def run(self, *middleware):
`middleware` is a list of WSGI middleware which is applied to the resulting WSGI
function.
"""
- return wsgi.runwsgi(self.wsgifunc(*middleware))
+ return wsgi.runwsgi(self.wsgifunc(*middleware), self)
+
+ def stop(self):
+ if self._simpleserver:
+ self._simpleserver.stop()
+ self._simpleserver = None
def cgirun(self, *middleware):
"""
View
@@ -131,7 +131,7 @@ def __init__(self, func, server_address):
print "http://%s:%d/" % server_address
WSGIServer(func, server_address).serve_forever()
-def runsimple(func, server_address=("0.0.0.0", 8080)):
+def runsimple(func, app, server_address=("0.0.0.0", 8080)):
"""
Runs [CherryPy][cp] WSGI server hosting WSGI app `func`.
The directory `static/` is hosted statically.
@@ -142,6 +142,7 @@ def runsimple(func, server_address=("0.0.0.0", 8080)):
func = LogMiddleware(func)
server = WSGIServer(server_address, func)
+ app._simpleserver = server
if server.ssl_adapter:
print "https://%s:%d/" % server_address
View
@@ -21,7 +21,7 @@ def runscgi(func, addr=('localhost', 4000)):
import flup.server.scgi as flups
return flups.WSGIServer(func, bindAddress=addr, debug=False).run()
-def runwsgi(func):
+def runwsgi(func, app):
"""
Runs a WSGI-compatible `func` using FCGI, SCGI, or a simple web server,
as appropriate based on context and `sys.argv`.
@@ -51,7 +51,7 @@ def runwsgi(func):
else:
return runscgi(func)
- return httpserver.runsimple(func, validip(listget(sys.argv, 1, '')))
+ return httpserver.runsimple(func, app, validip(listget(sys.argv, 1, '')))
def _is_dev_mode():
# quick hack to check if the program is running in dev mode.