Merge pull request #348 from r0fls/275

add async run
This commit is contained in:
Eli Uriegas 2017-01-26 10:37:52 -06:00 committed by GitHub
commit d1c4f3172f
3 changed files with 84 additions and 6 deletions

20
examples/run_async.py Normal file
View File

@ -0,0 +1,20 @@
from sanic import Sanic
from sanic.response import json
from multiprocessing import Event
from signal import signal, SIGINT
import asyncio
app = Sanic(__name__)
@app.route("/")
async def test(request):
return json({"answer": "42"})
server = app.create_server(host="0.0.0.0", port=8001)
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(server)
signal(SIGINT, lambda s, f: loop.close())
try:
loop.run_forever()
except:
loop.stop()

View File

@ -348,11 +348,10 @@ class Sanic:
log.debug(self.config.LOGO) log.debug(self.config.LOGO)
# Serve # Serve
if ssl is None:
proto = "http" proto = "http"
else: if ssl is not None:
proto = "https" proto = "https"
log.info('Goin\' Fast @ {}://{}:{}'.format(proto, host, port)) log.info('Goin\' Fast @ {}://{}:{}', proto, host, port)
try: try:
if workers == 1: if workers == 1:
@ -378,6 +377,63 @@ class Sanic:
self.sock.close() self.sock.close()
get_event_loop().stop() get_event_loop().stop()
async def create_server(self, host="127.0.0.1", port=8000, debug=False,
before_start=None, after_start=None,
before_stop=None, after_stop=None, ssl=None,
sock=None, loop=None, protocol=HttpProtocol,
backlog=100, stop_event=None):
"""
Asynchronous version of `run`.
"""
loop = get_event_loop()
server_settings = {
'protocol': protocol,
'host': host,
'port': port,
'sock': sock,
'ssl': ssl,
'debug': debug,
'request_handler': self.handle_request,
'error_handler': self.error_handler,
'request_timeout': self.config.REQUEST_TIMEOUT,
'request_max_size': self.config.REQUEST_MAX_SIZE,
'loop': loop,
'backlog': backlog
}
# -------------------------------------------- #
# Register start/stop events
# -------------------------------------------- #
for event_name, settings_name, args, reverse in (
("before_server_start", "before_start", before_start, False),
("after_server_start", "after_start", after_start, False),
("before_server_stop", "before_stop", before_stop, True),
("after_server_stop", "after_stop", after_stop, True),
):
listeners = []
for blueprint in self.blueprints.values():
listeners += blueprint.listeners[event_name]
if args:
if callable(args):
args = [args]
listeners += args
if reverse:
listeners.reverse()
# Prepend sanic to the arguments when listeners are triggered
listeners = [partial(listener, self) for listener in listeners]
server_settings[settings_name] = listeners
server_settings['run_async'] = True
# Serve
proto = "http"
if ssl is not None:
proto = "https"
log.info('Goin\' Fast @ {}://{}:{}', proto, host, port)
return await serve(**server_settings)
def serve_multiple(self, server_settings, workers, stop_event=None): def serve_multiple(self, server_settings, workers, stop_event=None):
""" """
Starts multiple server processes simultaneously. Stops on interrupt Starts multiple server processes simultaneously. Stops on interrupt

View File

@ -261,7 +261,7 @@ def serve(host, port, request_handler, error_handler, before_start=None,
after_start=None, before_stop=None, after_stop=None, debug=False, after_start=None, before_stop=None, after_stop=None, debug=False,
request_timeout=60, ssl=None, sock=None, request_max_size=None, request_timeout=60, ssl=None, sock=None, request_max_size=None,
reuse_port=False, loop=None, protocol=HttpProtocol, backlog=100, reuse_port=False, loop=None, protocol=HttpProtocol, backlog=100,
register_sys_signals=True): register_sys_signals=True, run_async=False):
""" """
Starts asynchronous HTTP Server on an individual process. Starts asynchronous HTTP Server on an individual process.
@ -319,11 +319,13 @@ def serve(host, port, request_handler, error_handler, before_start=None,
sock=sock, sock=sock,
backlog=backlog backlog=backlog
) )
# Instead of pulling time at the end of every request, # Instead of pulling time at the end of every request,
# pull it once per minute # pull it once per minute
loop.call_soon(partial(update_current_time, loop)) loop.call_soon(partial(update_current_time, loop))
if run_async:
return server_coroutine
try: try:
http_server = loop.run_until_complete(server_coroutine) http_server = loop.run_until_complete(server_coroutine)
except Exception: except Exception: