Removes the need for asycnio global settings
Also moves sanic.py -> app.py and removes the need for us to relative import anymore. This is a step towards allowing people to use things like `sanic.get_event_loop()` instead of having to set global asyncio settings. Does not seem to work on 3.5.1 but works fine on every version after that.
This commit is contained in:
parent
c91d264ff1
commit
7f85be43c6
|
@ -1,5 +1,6 @@
|
||||||
from .sanic import Sanic
|
from sanic.app import Sanic
|
||||||
from .blueprints import Blueprint
|
from sanic.blueprints import Blueprint
|
||||||
|
|
||||||
|
|
||||||
__version__ = '0.3.0'
|
__version__ = '0.3.0'
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,25 @@
|
||||||
import logging
|
import logging
|
||||||
from asyncio import get_event_loop
|
import multiprocessing
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from inspect import isawaitable, stack, getmodulename
|
from inspect import isawaitable, stack, getmodulename
|
||||||
from traceback import format_exc
|
from traceback import format_exc
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from .config import Config
|
from sanic.policy import get_event_loop
|
||||||
from .constants import HTTP_METHODS
|
from sanic.config import Config
|
||||||
from .exceptions import Handler
|
from sanic.constants import HTTP_METHODS
|
||||||
from .exceptions import ServerError
|
from sanic.exceptions import Handler
|
||||||
from .log import log
|
from sanic.exceptions import ServerError
|
||||||
from .response import HTTPResponse
|
from sanic.log import log
|
||||||
from .router import Router
|
from sanic.response import HTTPResponse
|
||||||
from .server import serve, serve_multiple, HttpProtocol
|
from sanic.router import Router
|
||||||
from .static import register as static_register
|
from sanic.server import serve, serve_multiple, HttpProtocol
|
||||||
|
from sanic.static import register as static_register
|
||||||
|
|
||||||
|
|
||||||
class Sanic:
|
class Sanic:
|
||||||
|
|
||||||
def __init__(self, name=None, router=None,
|
def __init__(self, name=None, router=None,
|
||||||
error_handler=None):
|
error_handler=None):
|
||||||
# Only set up a default log handler if the
|
# Only set up a default log handler if the
|
||||||
|
@ -306,52 +308,33 @@ class Sanic:
|
||||||
:param protocol: Subclass of asyncio protocol class
|
:param protocol: Subclass of asyncio protocol class
|
||||||
:return: Nothing
|
:return: Nothing
|
||||||
"""
|
"""
|
||||||
server_settings = self._helper(
|
server_settings = self._get_server_settings(
|
||||||
host=host, port=port, debug=debug, before_start=before_start,
|
host=host, port=port, debug=debug, before_start=before_start,
|
||||||
after_start=after_start, before_stop=before_stop,
|
after_start=after_start, before_stop=before_stop,
|
||||||
after_stop=after_stop, ssl=ssl, sock=sock, workers=workers,
|
after_stop=after_stop, ssl=ssl, sock=sock, workers=workers,
|
||||||
loop=loop, protocol=protocol, backlog=backlog,
|
loop=loop, protocol=protocol, backlog=backlog,
|
||||||
stop_event=stop_event, register_sys_signals=register_sys_signals)
|
stop_event=stop_event, register_sys_signals=register_sys_signals)
|
||||||
|
log.info(
|
||||||
|
'Goin\' Fast @ {}://{}:{}'.format(
|
||||||
|
'https' if ssl else 'http', host, port))
|
||||||
try:
|
try:
|
||||||
if workers == 1:
|
if workers == 1:
|
||||||
serve(**server_settings)
|
serve(**server_settings)
|
||||||
else:
|
else:
|
||||||
serve_multiple(server_settings, workers, stop_event)
|
serve_multiple(server_settings, workers, stop_event)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.exception(
|
log.exception(
|
||||||
'Experienced exception while trying to serve')
|
'Experienced exception while trying to serve')
|
||||||
|
|
||||||
log.info("Server Stopped")
|
log.info("Server Stopped")
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
"""This kills the Sanic"""
|
"""This kills the Sanic"""
|
||||||
|
for process in multiprocessing.active_children():
|
||||||
|
process.terminate()
|
||||||
get_event_loop().stop()
|
get_event_loop().stop()
|
||||||
|
|
||||||
async def create_server(self, host="127.0.0.1", port=8000, debug=False,
|
def _get_server_settings(
|
||||||
before_start=None, after_start=None,
|
self, host="127.0.0.1", port=8000, debug=False,
|
||||||
before_stop=None, after_stop=None, ssl=None,
|
|
||||||
sock=None, loop=None, protocol=HttpProtocol,
|
|
||||||
backlog=100, stop_event=None):
|
|
||||||
"""
|
|
||||||
Asynchronous version of `run`.
|
|
||||||
"""
|
|
||||||
server_settings = self._helper(
|
|
||||||
host=host, port=port, debug=debug, before_start=before_start,
|
|
||||||
after_start=after_start, before_stop=before_stop,
|
|
||||||
after_stop=after_stop, ssl=ssl, sock=sock, loop=loop,
|
|
||||||
protocol=protocol, backlog=backlog, stop_event=stop_event,
|
|
||||||
async_run=True)
|
|
||||||
|
|
||||||
# Serve
|
|
||||||
proto = "http"
|
|
||||||
if ssl is not None:
|
|
||||||
proto = "https"
|
|
||||||
log.info('Goin\' Fast @ {}://{}:{}'.format(proto, host, port))
|
|
||||||
|
|
||||||
return await serve(**server_settings)
|
|
||||||
|
|
||||||
def _helper(self, host="127.0.0.1", port=8000, debug=False,
|
|
||||||
before_start=None, after_start=None, before_stop=None,
|
before_start=None, after_start=None, before_stop=None,
|
||||||
after_stop=None, ssl=None, sock=None, workers=1, loop=None,
|
after_stop=None, ssl=None, sock=None, workers=1, loop=None,
|
||||||
protocol=HttpProtocol, backlog=100, stop_event=None,
|
protocol=HttpProtocol, backlog=100, stop_event=None,
|
||||||
|
@ -362,7 +345,6 @@ class Sanic:
|
||||||
|
|
||||||
self.error_handler.debug = debug
|
self.error_handler.debug = debug
|
||||||
self.debug = debug
|
self.debug = debug
|
||||||
self.loop = loop = get_event_loop()
|
|
||||||
|
|
||||||
if loop is not None:
|
if loop is not None:
|
||||||
if self.debug:
|
if self.debug:
|
||||||
|
@ -396,8 +378,7 @@ class Sanic:
|
||||||
("before_server_start", "before_start", before_start, False),
|
("before_server_start", "before_start", before_start, False),
|
||||||
("after_server_start", "after_start", after_start, False),
|
("after_server_start", "after_start", after_start, False),
|
||||||
("before_server_stop", "before_stop", before_stop, True),
|
("before_server_stop", "before_stop", before_stop, True),
|
||||||
("after_server_stop", "after_stop", after_stop, True),
|
("after_server_stop", "after_stop", after_stop, True)):
|
||||||
):
|
|
||||||
listeners = []
|
listeners = []
|
||||||
for blueprint in self.blueprints.values():
|
for blueprint in self.blueprints.values():
|
||||||
listeners += blueprint.listeners[event_name]
|
listeners += blueprint.listeners[event_name]
|
||||||
|
@ -415,13 +396,4 @@ class Sanic:
|
||||||
log.setLevel(logging.DEBUG)
|
log.setLevel(logging.DEBUG)
|
||||||
log.debug(self.config.LOGO)
|
log.debug(self.config.LOGO)
|
||||||
|
|
||||||
if run_async:
|
|
||||||
server_settings['run_async'] = True
|
|
||||||
|
|
||||||
# Serve
|
|
||||||
proto = "http"
|
|
||||||
if ssl is not None:
|
|
||||||
proto = "https"
|
|
||||||
log.info('Goin\' Fast @ {}://{}:{}'.format(proto, host, port))
|
|
||||||
|
|
||||||
return server_settings
|
return server_settings
|
13
sanic/policy.py
Normal file
13
sanic/policy.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import uvloop
|
||||||
|
|
||||||
|
_policy = uvloop.EventLoopPolicy()
|
||||||
|
|
||||||
|
def get_event_loop():
|
||||||
|
return _policy.get_event_loop()
|
||||||
|
|
||||||
|
def new_event_loop():
|
||||||
|
return _policy.new_event_loop()
|
||||||
|
|
||||||
|
def set_event_loop(loop):
|
||||||
|
_policy.set_event_loop(loop)
|
||||||
|
|
|
@ -14,16 +14,11 @@ import warnings
|
||||||
from httptools import HttpRequestParser
|
from httptools import HttpRequestParser
|
||||||
from httptools.parser.errors import HttpParserError
|
from httptools.parser.errors import HttpParserError
|
||||||
|
|
||||||
from .exceptions import ServerError
|
from sanic.policy import new_event_loop, set_event_loop
|
||||||
|
from sanic.log import log
|
||||||
try:
|
from sanic.request import Request
|
||||||
import uvloop as async_loop
|
from sanic.exceptions import (
|
||||||
except ImportError:
|
RequestTimeout, PayloadTooLarge, InvalidUsage, ServerError)
|
||||||
async_loop = asyncio
|
|
||||||
|
|
||||||
from .log import log
|
|
||||||
from .request import Request
|
|
||||||
from .exceptions import RequestTimeout, PayloadTooLarge, InvalidUsage
|
|
||||||
|
|
||||||
current_time = None
|
current_time = None
|
||||||
|
|
||||||
|
@ -297,8 +292,8 @@ def serve(host, port, request_handler, error_handler, before_start=None,
|
||||||
:param protocol: Subclass of asyncio protocol class
|
:param protocol: Subclass of asyncio protocol class
|
||||||
:return: Nothing
|
:return: Nothing
|
||||||
"""
|
"""
|
||||||
loop = async_loop.new_event_loop()
|
loop = new_event_loop()
|
||||||
asyncio.set_event_loop(loop)
|
set_event_loop(loop)
|
||||||
|
|
||||||
if debug:
|
if debug:
|
||||||
loop.set_debug(debug)
|
loop.set_debug(debug)
|
||||||
|
@ -371,6 +366,8 @@ def serve(host, port, request_handler, error_handler, before_start=None,
|
||||||
|
|
||||||
trigger_events(after_stop, loop)
|
trigger_events(after_stop, loop)
|
||||||
|
|
||||||
|
loop.stop()
|
||||||
|
|
||||||
loop.close()
|
loop.close()
|
||||||
|
|
||||||
|
|
||||||
|
@ -396,6 +393,8 @@ def serve_multiple(server_settings, workers, stop_event=None):
|
||||||
sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
|
sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
|
||||||
sock.bind((server_settings['host'], server_settings['port']))
|
sock.bind((server_settings['host'], server_settings['port']))
|
||||||
set_inheritable(sock.fileno(), True)
|
set_inheritable(sock.fileno(), True)
|
||||||
|
host = server_settings['host']
|
||||||
|
port = server_settings['port']
|
||||||
server_settings['sock'] = sock
|
server_settings['sock'] = sock
|
||||||
server_settings['host'] = None
|
server_settings['host'] = None
|
||||||
server_settings['port'] = None
|
server_settings['port'] = None
|
||||||
|
@ -420,5 +419,3 @@ def serve_multiple(server_settings, workers, stop_event=None):
|
||||||
for process in processes:
|
for process in processes:
|
||||||
process.terminate()
|
process.terminate()
|
||||||
sock.close()
|
sock.close()
|
||||||
|
|
||||||
asyncio.get_event_loop().stop()
|
|
||||||
|
|
|
@ -29,10 +29,11 @@ def sanic_endpoint_test(app, method='get', uri='/', gather_request=True,
|
||||||
|
|
||||||
async def _collect_response(sanic, loop):
|
async def _collect_response(sanic, loop):
|
||||||
try:
|
try:
|
||||||
response = await local_request(method, uri, *request_args,
|
response = await local_request(
|
||||||
**request_kwargs)
|
method, uri, *request_args, **request_kwargs)
|
||||||
results.append(response)
|
results.append(response)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
log.exception('Exception occured when collecting response')
|
||||||
exceptions.append(e)
|
exceptions.append(e)
|
||||||
app.stop()
|
app.stop()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user