From 94b2352c2c60a628b5fbc7e7ad0f0431f71b5dfa Mon Sep 17 00:00:00 2001 From: Raphael Deem Date: Sat, 11 Feb 2017 14:52:40 -0800 Subject: [PATCH] add ensure_future method --- sanic/sanic.py | 28 ++++++++++++++++++++++++++-- tests/test_ensure_future.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 tests/test_ensure_future.py diff --git a/sanic/sanic.py b/sanic/sanic.py index 951632be..218937c5 100644 --- a/sanic/sanic.py +++ b/sanic/sanic.py @@ -1,7 +1,7 @@ import logging import re import warnings -from asyncio import get_event_loop +from asyncio import get_event_loop, ensure_future from collections import deque from functools import partial from inspect import isawaitable, stack, getmodulename @@ -44,7 +44,7 @@ class Sanic: self._blueprint_order = [] self.debug = None self.sock = None - self.processes = None + self.before_start = [] # Register alternative method names self.go_fast = self.run @@ -53,6 +53,23 @@ class Sanic: # Registration # -------------------------------------------------------------------- # + def ensure_future(self, task): + """ + Schedule a task to run later, after the loop has started. + Different from asyncio.ensure_future in that it does not + also return a future, and the actual ensure_future call + is delayed until before server start. + + :param task: A future, couroutine or awaitable. + """ + def run(app, loop): + if callable(task): + ensure_future(task()) + else: + ensure_future(task) + + self.before_start.append(run) + # Decorator def route(self, uri, methods=frozenset({'GET'}), host=None): """ @@ -397,6 +414,13 @@ class Sanic: :param protocol: Subclass of asyncio protocol class :return: Nothing """ + if before_start is not None: + if not isinstance(before_start, list): + before_start = [before_start] + before_start.extend(self.before_start) + else: + before_start = self.before_start + server_settings = self._helper( host=host, port=port, debug=debug, before_start=before_start, after_start=after_start, before_stop=before_stop, diff --git a/tests/test_ensure_future.py b/tests/test_ensure_future.py new file mode 100644 index 00000000..385d8b88 --- /dev/null +++ b/tests/test_ensure_future.py @@ -0,0 +1,30 @@ +import sanic +from sanic.utils import sanic_endpoint_test +from sanic.response import text +from threading import Event +import asyncio + +def test_ensure_future(): + e = Event() + async def coro(): + await asyncio.sleep(0.05) + e.set() + + app = sanic.Sanic() + app.ensure_future(coro) + + @app.route('/early') + def not_set(request): + return text(e.is_set()) + + @app.route('/late') + async def set(request): + await asyncio.sleep(0.1) + return text(e.is_set()) + + + request, response = sanic_endpoint_test(app, uri='/early') + assert response.body == b'False' + + request, response = sanic_endpoint_test(app, uri='/late') + assert response.body == b'True'