diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3416881..cc93d8e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,12 @@ Changelog ========= +Version 2.1.0 (29-04-2018) +----------------------------------------------------------- + +* Updating to support Channels 2.1.0 and the upcoming + ASGI spec changes (run application initialization in a thread) + Version 2.0.1 (27-04-2018) ----------------------------------------------------------- diff --git a/txasgiresource/__init__.py b/txasgiresource/__init__.py index 8e418bc..2a2fa18 100644 --- a/txasgiresource/__init__.py +++ b/txasgiresource/__init__.py @@ -9,4 +9,4 @@ except ImportError: pass -__version__ = '2.0.1' +__version__ = '2.1.0' diff --git a/txasgiresource/application.py b/txasgiresource/application.py index bea3fd2..ccd5ee5 100644 --- a/txasgiresource/application.py +++ b/txasgiresource/application.py @@ -1,7 +1,7 @@ import asyncio from concurrent.futures import CancelledError -from twisted.internet import defer +from twisted.internet import defer, threads class ApplicationManager: @@ -22,11 +22,12 @@ def stop(self): except CancelledError: pass + @defer.inlineCallbacks def create_application_instance(self, protocol, scope): async def handle_reply(msg): protocol.handle_reply(msg) - application_instance = self.application(scope) + application_instance = yield threads.deferToThread(self.application, scope) queue = asyncio.Queue() self.application_instances[protocol] = asyncio.ensure_future( diff --git a/txasgiresource/http.py b/txasgiresource/http.py index 1774551..2f2d4ee 100644 --- a/txasgiresource/http.py +++ b/txasgiresource/http.py @@ -113,7 +113,8 @@ def handle_reply(self, msg): self.reply_defer = defer.Deferred() d.callback(msg) - def render(self, request): + @defer.inlineCallbacks + def _render(self, request): self.request = request scope = dict(self.base_scope) @@ -122,10 +123,13 @@ def render(self, request): scope['scheme'] = 'http%s' % (scope.pop('_ssl')) scope['method'] = request.method.decode('utf8') - self.queue = self.application.create_application_instance(self, scope) + self.queue = yield self.application.create_application_instance(self, scope) self.send_request_to_application(request, request.content) + def render(self, request): + self._render(request) + return server.NOT_DONE_YET @defer.inlineCallbacks diff --git a/txasgiresource/ws.py b/txasgiresource/ws.py index dcd75d6..ae18ced 100644 --- a/txasgiresource/ws.py +++ b/txasgiresource/ws.py @@ -14,19 +14,15 @@ class ASGIWebSocketServerProtocol(WebSocketServerProtocol, policies.TimeoutMixin accept_promise = None queue = None - def onConnect(self, request): - self.request = request - self.setTimeout(self.factory.idle_timeout) - self.accept_promise = defer.Deferred() - self.reply_defer = defer.Deferred() - + @defer.inlineCallbacks + def _onConnect(self, request): scope = dict(self.factory.base_scope) scope['type'] = 'websocket' scope['scheme'] = 'ws%s' % (scope.pop('_ssl')) - # # TODO: add subprotocols + # TODO: add subprotocols try: - self.queue = self.factory.application.create_application_instance(self, scope) + self.queue = yield self.factory.application.create_application_instance(self, scope) self.opened = True except Exception as e: logger.exception('Failed to create application') @@ -36,6 +32,14 @@ def onConnect(self, request): self.send_replies() + def onConnect(self, request): + self.request = request + self.setTimeout(self.factory.idle_timeout) + self.accept_promise = defer.Deferred() + self.reply_defer = defer.Deferred() + + self._onConnect(request) + return self.accept_promise @defer.inlineCallbacks