@@ -65,8 +65,8 @@ def wrap_json_request_handler(h):
6565 The handler method must have a signature of "handle_foo(self, request)",
6666 where "request" must be a SynapseRequest.
6767
68- The handler must return a deferred. If the deferred succeeds we assume that
69- a response has been sent. If the deferred fails with a SynapseError we use
68+ The handler must return a deferred or a coroutine . If the deferred succeeds
69+ we assume that a response has been sent. If the deferred fails with a SynapseError we use
7070 it to send a JSON response with the appropriate HTTP reponse code. If the
7171 deferred fails with any other type of error we send a 500 reponse.
7272 """
@@ -353,16 +353,22 @@ def render(self, request):
353353 """
354354 Render the request, using an asynchronous render handler if it exists.
355355 """
356- render_callback_name = "_async_render_" + request .method .decode ("ascii" )
356+ async_render_callback_name = "_async_render_" + request .method .decode ("ascii" )
357357
358- if hasattr (self , render_callback_name ):
359- # Call the handler
360- callback = getattr (self , render_callback_name )
361- defer .ensureDeferred (callback (request ))
358+ # Try and get the async renderer
359+ callback = getattr (self , async_render_callback_name , None )
362360
363- return NOT_DONE_YET
364- else :
365- super ().render (request )
361+ # No async renderer for this request method.
362+ if not callback :
363+ return super ().render (request )
364+
365+ resp = callback (request )
366+
367+ # If it's a coroutine, turn it into a Deferred
368+ if isinstance (resp , types .CoroutineType ):
369+ defer .ensureDeferred (resp )
370+
371+ return NOT_DONE_YET
366372
367373
368374def _options_handler (request ):
0 commit comments