Merge pull request #335 from r0fls/remove-loop
remove loop as argument and update examples
This commit is contained in:
commit
fad9fbca6f
|
@ -1,12 +1,8 @@
|
||||||
from sanic import Sanic
|
from sanic import Sanic
|
||||||
from sanic.response import json
|
from sanic.response import json
|
||||||
|
|
||||||
import uvloop
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
|
||||||
#Create an event loop manually so that we can use it for both sanic & aiohttp
|
|
||||||
loop = uvloop.new_event_loop()
|
|
||||||
|
|
||||||
app = Sanic(__name__)
|
app = Sanic(__name__)
|
||||||
|
|
||||||
async def fetch(session, url):
|
async def fetch(session, url):
|
||||||
|
@ -24,10 +20,9 @@ async def test(request):
|
||||||
"""
|
"""
|
||||||
url = "https://api.github.com/repos/channelcat/sanic"
|
url = "https://api.github.com/repos/channelcat/sanic"
|
||||||
|
|
||||||
async with aiohttp.ClientSession(loop=loop) as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
response = await fetch(session, url)
|
response = await fetch(session, url)
|
||||||
return json(response)
|
return json(response)
|
||||||
|
|
||||||
|
|
||||||
app.run(host="0.0.0.0", port=8000, loop=loop)
|
app.run(host="0.0.0.0", port=8000, workers=2)
|
||||||
|
|
||||||
|
|
36
examples/limit_concurrency.py
Normal file
36
examples/limit_concurrency.py
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
from sanic import Sanic
|
||||||
|
from sanic.response import json
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import aiohttp
|
||||||
|
|
||||||
|
app = Sanic(__name__)
|
||||||
|
|
||||||
|
sem = None
|
||||||
|
|
||||||
|
def init(sanic, loop):
|
||||||
|
global sem
|
||||||
|
CONCURRENCY_PER_WORKER = 4
|
||||||
|
sem = asyncio.Semaphore(CONCURRENCY_PER_WORKER, loop=loop)
|
||||||
|
|
||||||
|
async def bounded_fetch(session, url):
|
||||||
|
"""
|
||||||
|
Use session object to perform 'get' request on url
|
||||||
|
"""
|
||||||
|
async with sem, session.get(url) as response:
|
||||||
|
return await response.json()
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/")
|
||||||
|
async def test(request):
|
||||||
|
"""
|
||||||
|
Download and serve example JSON
|
||||||
|
"""
|
||||||
|
url = "https://api.github.com/repos/channelcat/sanic"
|
||||||
|
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
response = await bounded_fetch(session, url)
|
||||||
|
return json(response)
|
||||||
|
|
||||||
|
|
||||||
|
app.run(host="0.0.0.0", port=8000, workers=2, before_start=init)
|
|
@ -10,8 +10,6 @@ import aiopg
|
||||||
from sanic import Sanic
|
from sanic import Sanic
|
||||||
from sanic.response import json
|
from sanic.response import json
|
||||||
|
|
||||||
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
|
|
||||||
|
|
||||||
database_name = os.environ['DATABASE_NAME']
|
database_name = os.environ['DATABASE_NAME']
|
||||||
database_host = os.environ['DATABASE_HOST']
|
database_host = os.environ['DATABASE_HOST']
|
||||||
database_user = os.environ['DATABASE_USER']
|
database_user = os.environ['DATABASE_USER']
|
||||||
|
@ -21,45 +19,47 @@ connection = 'postgres://{0}:{1}@{2}/{3}'.format(database_user,
|
||||||
database_password,
|
database_password,
|
||||||
database_host,
|
database_host,
|
||||||
database_name)
|
database_name)
|
||||||
loop = asyncio.get_event_loop()
|
|
||||||
|
|
||||||
|
|
||||||
async def get_pool():
|
async def get_pool():
|
||||||
return await aiopg.create_pool(connection)
|
return await aiopg.create_pool(connection)
|
||||||
|
|
||||||
app = Sanic(name=__name__)
|
app = Sanic(name=__name__)
|
||||||
pool = loop.run_until_complete(get_pool())
|
|
||||||
|
|
||||||
|
|
||||||
async def prepare_db():
|
|
||||||
""" Let's create some table and add some data
|
|
||||||
|
|
||||||
|
async def prepare_db(app, loop):
|
||||||
"""
|
"""
|
||||||
async with pool.acquire() as conn:
|
Let's create some table and add some data
|
||||||
async with conn.cursor() as cur:
|
"""
|
||||||
await cur.execute('DROP TABLE IF EXISTS sanic_polls')
|
async with aiopg.create_pool(connection) as pool:
|
||||||
await cur.execute("""CREATE TABLE sanic_polls (
|
async with pool.acquire() as conn:
|
||||||
id serial primary key,
|
async with conn.cursor() as cur:
|
||||||
question varchar(50),
|
await cur.execute('DROP TABLE IF EXISTS sanic_polls')
|
||||||
pub_date timestamp
|
await cur.execute("""CREATE TABLE sanic_polls (
|
||||||
);""")
|
id serial primary key,
|
||||||
for i in range(0, 100):
|
question varchar(50),
|
||||||
await cur.execute("""INSERT INTO sanic_polls
|
pub_date timestamp
|
||||||
(id, question, pub_date) VALUES ({}, {}, now())
|
);""")
|
||||||
""".format(i, i))
|
for i in range(0, 100):
|
||||||
|
await cur.execute("""INSERT INTO sanic_polls
|
||||||
|
(id, question, pub_date) VALUES ({}, {}, now())
|
||||||
|
""".format(i, i))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
async def handle(request):
|
async def handle(request):
|
||||||
async with pool.acquire() as conn:
|
result = []
|
||||||
async with conn.cursor() as cur:
|
async def test_select():
|
||||||
result = []
|
async with aiopg.create_pool(connection) as pool:
|
||||||
await cur.execute("SELECT question, pub_date FROM sanic_polls")
|
async with pool.acquire() as conn:
|
||||||
async for row in cur:
|
async with conn.cursor() as cur:
|
||||||
result.append({"question": row[0], "pub_date": row[1]})
|
await cur.execute("SELECT question, pub_date FROM sanic_polls")
|
||||||
return json({"polls": result})
|
async for row in cur:
|
||||||
|
result.append({"question": row[0], "pub_date": row[1]})
|
||||||
|
res = await test_select()
|
||||||
|
return json({'polls': result})
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
loop.run_until_complete(prepare_db())
|
app.run(host='0.0.0.0',
|
||||||
app.run(host='0.0.0.0', port=8000, loop=loop)
|
port=8000,
|
||||||
|
debug=True,
|
||||||
|
before_start=prepare_db)
|
||||||
|
|
|
@ -12,8 +12,6 @@ import sqlalchemy as sa
|
||||||
from sanic import Sanic
|
from sanic import Sanic
|
||||||
from sanic.response import json
|
from sanic.response import json
|
||||||
|
|
||||||
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
|
|
||||||
|
|
||||||
database_name = os.environ['DATABASE_NAME']
|
database_name = os.environ['DATABASE_NAME']
|
||||||
database_host = os.environ['DATABASE_HOST']
|
database_host = os.environ['DATABASE_HOST']
|
||||||
database_user = os.environ['DATABASE_USER']
|
database_user = os.environ['DATABASE_USER']
|
||||||
|
@ -23,8 +21,6 @@ connection = 'postgres://{0}:{1}@{2}/{3}'.format(database_user,
|
||||||
database_password,
|
database_password,
|
||||||
database_host,
|
database_host,
|
||||||
database_name)
|
database_name)
|
||||||
loop = asyncio.get_event_loop()
|
|
||||||
|
|
||||||
|
|
||||||
metadata = sa.MetaData()
|
metadata = sa.MetaData()
|
||||||
|
|
||||||
|
@ -34,40 +30,37 @@ polls = sa.Table('sanic_polls', metadata,
|
||||||
sa.Column("pub_date", sa.DateTime))
|
sa.Column("pub_date", sa.DateTime))
|
||||||
|
|
||||||
|
|
||||||
async def get_engine():
|
|
||||||
return await create_engine(connection)
|
|
||||||
|
|
||||||
app = Sanic(name=__name__)
|
app = Sanic(name=__name__)
|
||||||
engine = loop.run_until_complete(get_engine())
|
|
||||||
|
|
||||||
|
|
||||||
async def prepare_db():
|
async def prepare_db(app, loop):
|
||||||
""" Let's add some data
|
""" Let's add some data
|
||||||
|
|
||||||
"""
|
"""
|
||||||
async with engine.acquire() as conn:
|
async with create_engine(connection) as engine:
|
||||||
await conn.execute('DROP TABLE IF EXISTS sanic_polls')
|
async with engine.acquire() as conn:
|
||||||
await conn.execute("""CREATE TABLE sanic_polls (
|
await conn.execute('DROP TABLE IF EXISTS sanic_polls')
|
||||||
id serial primary key,
|
await conn.execute("""CREATE TABLE sanic_polls (
|
||||||
question varchar(50),
|
id serial primary key,
|
||||||
pub_date timestamp
|
question varchar(50),
|
||||||
);""")
|
pub_date timestamp
|
||||||
for i in range(0, 100):
|
);""")
|
||||||
await conn.execute(
|
for i in range(0, 100):
|
||||||
polls.insert().values(question=i,
|
await conn.execute(
|
||||||
pub_date=datetime.datetime.now())
|
polls.insert().values(question=i,
|
||||||
)
|
pub_date=datetime.datetime.now())
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
async def handle(request):
|
async def handle(request):
|
||||||
async with engine.acquire() as conn:
|
async with create_engine(connection) as engine:
|
||||||
result = []
|
async with engine.acquire() as conn:
|
||||||
async for row in conn.execute(polls.select()):
|
result = []
|
||||||
result.append({"question": row.question, "pub_date": row.pub_date})
|
async for row in conn.execute(polls.select()):
|
||||||
return json({"polls": result})
|
result.append({"question": row.question, "pub_date": row.pub_date})
|
||||||
|
return json({"polls": result})
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
loop.run_until_complete(prepare_db())
|
app.run(host='0.0.0.0', port=8000, before_start=prepare_db)
|
||||||
app.run(host='0.0.0.0', port=8000, loop=loop)
|
|
||||||
|
|
|
@ -10,8 +10,6 @@ from asyncpg import create_pool
|
||||||
from sanic import Sanic
|
from sanic import Sanic
|
||||||
from sanic.response import json
|
from sanic.response import json
|
||||||
|
|
||||||
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
|
|
||||||
|
|
||||||
DB_CONFIG = {
|
DB_CONFIG = {
|
||||||
'host': '<host>',
|
'host': '<host>',
|
||||||
'user': '<username>',
|
'user': '<username>',
|
||||||
|
@ -21,45 +19,40 @@ DB_CONFIG = {
|
||||||
}
|
}
|
||||||
|
|
||||||
def jsonify(records):
|
def jsonify(records):
|
||||||
""" Parse asyncpg record response into JSON format
|
"""
|
||||||
|
Parse asyncpg record response into JSON format
|
||||||
"""
|
"""
|
||||||
return [{key: value for key, value in
|
return [{key: value for key, value in
|
||||||
zip(r.keys(), r.values())} for r in records]
|
zip(r.keys(), r.values())} for r in records]
|
||||||
|
|
||||||
loop = asyncio.get_event_loop()
|
|
||||||
|
|
||||||
async def make_pool():
|
|
||||||
return await create_pool(**DB_CONFIG)
|
|
||||||
|
|
||||||
app = Sanic(__name__)
|
app = Sanic(__name__)
|
||||||
pool = loop.run_until_complete(make_pool())
|
|
||||||
|
|
||||||
async def create_db():
|
|
||||||
""" Create some table and add some data
|
|
||||||
|
|
||||||
|
async def create_db(app, loop):
|
||||||
"""
|
"""
|
||||||
async with pool.acquire() as connection:
|
Create some table and add some data
|
||||||
async with connection.transaction():
|
"""
|
||||||
await connection.execute('DROP TABLE IF EXISTS sanic_post')
|
async with create_pool(**DB_CONFIG) as pool:
|
||||||
await connection.execute("""CREATE TABLE sanic_post (
|
async with pool.acquire() as connection:
|
||||||
id serial primary key,
|
async with connection.transaction():
|
||||||
content varchar(50),
|
await connection.execute('DROP TABLE IF EXISTS sanic_post')
|
||||||
post_date timestamp
|
await connection.execute("""CREATE TABLE sanic_post (
|
||||||
);""")
|
id serial primary key,
|
||||||
for i in range(0, 100):
|
content varchar(50),
|
||||||
await connection.execute(f"""INSERT INTO sanic_post
|
post_date timestamp
|
||||||
(id, content, post_date) VALUES ({i}, {i}, now())""")
|
);""")
|
||||||
|
for i in range(0, 100):
|
||||||
|
await connection.execute(f"""INSERT INTO sanic_post
|
||||||
|
(id, content, post_date) VALUES ({i}, {i}, now())""")
|
||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
async def handler(request):
|
async def handler(request):
|
||||||
async with pool.acquire() as connection:
|
async with create_pool(**DB_CONFIG) as pool:
|
||||||
async with connection.transaction():
|
async with pool.acquire() as connection:
|
||||||
results = await connection.fetch('SELECT * FROM sanic_post')
|
async with connection.transaction():
|
||||||
return json({'posts': jsonify(results)})
|
results = await connection.fetch('SELECT * FROM sanic_post')
|
||||||
|
return json({'posts': jsonify(results)})
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
loop.run_until_complete(create_db())
|
app.run(host='0.0.0.0', port=8000, before_start=create_db)
|
||||||
app.run(host='0.0.0.0', port=8000, loop=loop)
|
|
||||||
|
|
|
@ -9,19 +9,18 @@ from sanic import Sanic
|
||||||
from sanic.response import json
|
from sanic.response import json
|
||||||
|
|
||||||
## peewee_async related imports
|
## peewee_async related imports
|
||||||
import uvloop
|
|
||||||
import peewee
|
import peewee
|
||||||
from peewee_async import Manager, PostgresqlDatabase
|
from peewee_async import Manager, PostgresqlDatabase
|
||||||
|
|
||||||
# we instantiate a custom loop so we can pass it to our db manager
|
# we instantiate a custom loop so we can pass it to our db manager
|
||||||
loop = uvloop.new_event_loop()
|
|
||||||
|
|
||||||
database = PostgresqlDatabase(database='test',
|
def setup(app, loop):
|
||||||
host='127.0.0.1',
|
database = PostgresqlDatabase(database='test',
|
||||||
user='postgres',
|
host='127.0.0.1',
|
||||||
password='mysecretpassword')
|
user='postgres',
|
||||||
|
password='mysecretpassword')
|
||||||
|
|
||||||
objects = Manager(database, loop=loop)
|
objects = Manager(database, loop=loop)
|
||||||
|
|
||||||
## from peewee_async docs:
|
## from peewee_async docs:
|
||||||
# Also there’s no need to connect and re-connect before executing async queries
|
# Also there’s no need to connect and re-connect before executing async queries
|
||||||
|
@ -76,5 +75,4 @@ async def get(request):
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app.run(host='0.0.0.0', port=8000, loop=loop)
|
app.run(host='0.0.0.0', port=8000, before_start=setup)
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,6 @@ class Sanic:
|
||||||
self.response_middleware = deque()
|
self.response_middleware = deque()
|
||||||
self.blueprints = {}
|
self.blueprints = {}
|
||||||
self._blueprint_order = []
|
self._blueprint_order = []
|
||||||
self.loop = None
|
|
||||||
self.debug = None
|
self.debug = None
|
||||||
self.sock = None
|
self.sock = None
|
||||||
self.processes = None
|
self.processes = None
|
||||||
|
@ -296,7 +295,6 @@ class Sanic:
|
||||||
:param sock: Socket for the server to accept connections from
|
:param sock: Socket for the server to accept connections from
|
||||||
:param workers: Number of processes
|
:param workers: Number of processes
|
||||||
received before it is respected
|
received before it is respected
|
||||||
:param loop: asyncio compatible event loop
|
|
||||||
:param protocol: Subclass of asyncio protocol class
|
:param protocol: Subclass of asyncio protocol class
|
||||||
:return: Nothing
|
:return: Nothing
|
||||||
"""
|
"""
|
||||||
|
@ -319,7 +317,6 @@ class Sanic:
|
||||||
'error_handler': self.error_handler,
|
'error_handler': self.error_handler,
|
||||||
'request_timeout': self.config.REQUEST_TIMEOUT,
|
'request_timeout': self.config.REQUEST_TIMEOUT,
|
||||||
'request_max_size': self.config.REQUEST_MAX_SIZE,
|
'request_max_size': self.config.REQUEST_MAX_SIZE,
|
||||||
'loop': loop,
|
|
||||||
'register_sys_signals': register_sys_signals,
|
'register_sys_signals': register_sys_signals,
|
||||||
'backlog': backlog
|
'backlog': backlog
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,7 +289,7 @@ 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 = loop or async_loop.new_event_loop()
|
loop = async_loop.new_event_loop()
|
||||||
asyncio.set_event_loop(loop)
|
asyncio.set_event_loop(loop)
|
||||||
|
|
||||||
if debug:
|
if debug:
|
||||||
|
|
|
@ -16,7 +16,7 @@ async def local_request(method, uri, cookies=None, *args, **kwargs):
|
||||||
|
|
||||||
|
|
||||||
def sanic_endpoint_test(app, method='get', uri='/', gather_request=True,
|
def sanic_endpoint_test(app, method='get', uri='/', gather_request=True,
|
||||||
loop=None, debug=False, server_kwargs={},
|
debug=False, server_kwargs={},
|
||||||
*request_args, **request_kwargs):
|
*request_args, **request_kwargs):
|
||||||
results = []
|
results = []
|
||||||
exceptions = []
|
exceptions = []
|
||||||
|
@ -36,7 +36,7 @@ def sanic_endpoint_test(app, method='get', uri='/', gather_request=True,
|
||||||
app.stop()
|
app.stop()
|
||||||
|
|
||||||
app.run(host=HOST, debug=debug, port=PORT,
|
app.run(host=HOST, debug=debug, port=PORT,
|
||||||
after_start=_collect_response, loop=loop, **server_kwargs)
|
after_start=_collect_response, **server_kwargs)
|
||||||
|
|
||||||
if exceptions:
|
if exceptions:
|
||||||
raise ValueError("Exception during request: {}".format(exceptions))
|
raise ValueError("Exception during request: {}".format(exceptions))
|
||||||
|
|
|
@ -4,12 +4,20 @@ from sanic.utils import HOST, PORT
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock
|
||||||
import pytest
|
import pytest
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from queue import Queue
|
||||||
|
|
||||||
|
|
||||||
async def stop(app):
|
async def stop(app, loop):
|
||||||
await asyncio.sleep(0.2)
|
await asyncio.sleep(0.1)
|
||||||
app.stop()
|
app.stop()
|
||||||
|
|
||||||
|
calledq = Queue()
|
||||||
|
|
||||||
|
def set_loop(app, loop):
|
||||||
|
loop.add_signal_handler = MagicMock()
|
||||||
|
|
||||||
|
def after(app, loop):
|
||||||
|
calledq.put(loop.add_signal_handler.called)
|
||||||
|
|
||||||
def test_register_system_signals():
|
def test_register_system_signals():
|
||||||
"""Test if sanic register system signals"""
|
"""Test if sanic register system signals"""
|
||||||
|
@ -19,11 +27,11 @@ def test_register_system_signals():
|
||||||
async def hello_route(request):
|
async def hello_route(request):
|
||||||
return HTTPResponse()
|
return HTTPResponse()
|
||||||
|
|
||||||
loop = asyncio.new_event_loop()
|
app.run(HOST, PORT,
|
||||||
loop.add_signal_handler = MagicMock()
|
before_start=set_loop,
|
||||||
asyncio.ensure_future(stop(app), loop=loop)
|
after_start=stop,
|
||||||
app.run(HOST, PORT, loop=loop)
|
after_stop=after)
|
||||||
assert loop.add_signal_handler.called == True
|
assert calledq.get() == True
|
||||||
|
|
||||||
|
|
||||||
def test_dont_register_system_signals():
|
def test_dont_register_system_signals():
|
||||||
|
@ -34,8 +42,9 @@ def test_dont_register_system_signals():
|
||||||
async def hello_route(request):
|
async def hello_route(request):
|
||||||
return HTTPResponse()
|
return HTTPResponse()
|
||||||
|
|
||||||
loop = asyncio.new_event_loop()
|
app.run(HOST, PORT,
|
||||||
loop.add_signal_handler = MagicMock()
|
before_start=set_loop,
|
||||||
asyncio.ensure_future(stop(app), loop=loop)
|
after_start=stop,
|
||||||
app.run(HOST, PORT, loop=loop, register_sys_signals=False)
|
after_stop=after,
|
||||||
assert loop.add_signal_handler.called == False
|
register_sys_signals=False)
|
||||||
|
assert calledq.get() == False
|
Loading…
Reference in New Issue
Block a user