Skip to content

Commit

Permalink
Revert #3194
Browse files Browse the repository at this point in the history
  • Loading branch information
asvetlov committed Oct 21, 2018
1 parent 1778189 commit 63471be
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 86 deletions.
1 change: 0 additions & 1 deletion CHANGES/3191.feature

This file was deleted.

60 changes: 19 additions & 41 deletions aiohttp/web_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ def __init__(self, *,
self._on_startup = Signal(self) # type: _AppSignal
self._on_shutdown = Signal(self) # type: _AppSignal
self._on_cleanup = Signal(self) # type: _AppSignal
self._cleanup_ctx = CleanupContext(self._on_startup)
self._cleanup_ctx = CleanupContext()
self._on_startup.append(self._cleanup_ctx._on_startup)
self._on_cleanup.append(self._cleanup_ctx._on_cleanup)
self._client_max_size = client_max_size

Expand Down Expand Up @@ -446,60 +447,37 @@ def exceptions(self) -> List[BaseException]:
return self.args[1]


class _CleanupContextItem:
"""
CleanupContext uses this class to wrap an asynchronous generator
before adding to itself.
"""

def __init__(self,
cb: Callable[[Application], AsyncIterator[None]]) -> None:
self._cb = cb
self._iterator_at_exit = None # type: Optional[AsyncIterator[None]]

async def _enter(self, app: Application) -> None:
it = self._cb(app).__aiter__()
await it.__anext__()
self._iterator_at_exit = it

async def _exit(self, app: Application) -> None:
if self._iterator_at_exit is None:
return
try:
await self._iterator_at_exit.__anext__()
except StopAsyncIteration:
pass
else:
raise RuntimeError("{!r} has more than one 'yield'"
.format(self._iterator_at_exit))


if TYPE_CHECKING: # pragma: no branch
_CleanupContextBase = FrozenList[_CleanupContextItem]
_CleanupContextBase = FrozenList[Callable[[Application],
AsyncIterator[None]]]
else:
_CleanupContextBase = FrozenList


class CleanupContext(_CleanupContextBase):

def __init__(self, on_startup: _AppSignal):
def __init__(self) -> None:
super().__init__()
self._on_startup = on_startup
self._exits = [] # type: List[AsyncIterator[None]]

def append(self, # type: ignore
item: Callable[[Application], AsyncIterator[None]]) -> None:
cleanup_ctx_item = _CleanupContextItem(item)
super().append(cleanup_ctx_item._exit) # type: ignore
self._on_startup.append(cleanup_ctx_item._enter)
async def _on_startup(self, app: Application) -> None:
for cb in self:
it = cb(app).__aiter__()
await it.__anext__()
self._exits.append(it)

async def _on_cleanup(self, app: Application):
async def _on_cleanup(self, app: Application) -> None:
errors = []
for cb in reversed(self):
for it in reversed(self._exits):
try:
await cb(app) # type: ignore
await it.__anext__()
except StopAsyncIteration:
pass
except Exception as exc:
errors.append(exc)

else:
errors.append(RuntimeError("{!r} has more than one 'yield'"
.format(it)))
if errors:
if len(errors) == 1:
raise errors[0]
Expand Down
7 changes: 0 additions & 7 deletions docs/web_advanced.rst
Original file line number Diff line number Diff line change
Expand Up @@ -619,13 +619,6 @@ one ``yield``.
*aiohttp* guarantees that *cleanup code* is called if and only if
*startup code* was successfully finished.

*statup codes* are called in order of insertion. The order is preserved between
callbacks in *cleanup* signal and *statup codes*.

*cleanup codes* are called in reverse order of insertion before any
callback in *cleanup* signal.


Asynchronous generators are supported by Python 3.6+, on Python 3.5
please use `async_generator <https://pypi.org/project/async_generator/>`_
library.
Expand Down
37 changes: 0 additions & 37 deletions tests/test_web_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,43 +415,6 @@ async def inner(app):
assert out == ['pre_1', 'post_1']


async def test_mixe_cleanup_ctx_on_startup_and_on_cleanup() -> None:
app = web.Application()
out = []

def startup(num):
async def inner(app):
out.append('pre_' + str(num))
return inner

def cleanup(num):
async def inner(app):
out.append('post_' + str(num))
return inner

def cleanup_ctx(num):
@async_generator
async def inner(app):
out.append('pre_' + str(num))
await yield_(None)
out.append('post_' + str(num))
return inner

app.on_startup.append(startup(1))
app.cleanup_ctx.append(cleanup_ctx(2))
app.on_startup.append(startup(3))
app.cleanup_ctx.append(cleanup_ctx(4))
app.on_startup.append(startup(5))

app.freeze()
await app.startup()
assert out == ['pre_1', 'pre_2', 'pre_3', 'pre_4', 'pre_5']

del out[:]
await app.cleanup()
assert out == ['post_4', 'post_2']


async def test_subapp_chained_config_dict_visibility(aiohttp_client) -> None:

async def main_handler(request):
Expand Down

0 comments on commit 63471be

Please sign in to comment.