Add performant smart response handling

This commit is contained in:
Eli Uriegas 2016-12-25 09:49:54 -08:00
parent 6cf3754051
commit d3e99c9a35
2 changed files with 72 additions and 4 deletions

View File

@ -6,7 +6,9 @@ from signal import SIGINT, SIGTERM
from time import time
from httptools import HttpRequestParser
from httptools.parser.errors import HttpParserError
from .exceptions import ServerError
from .response import json, text
try:
import uvloop as async_loop
@ -147,12 +149,29 @@ class HttpProtocol(asyncio.Protocol):
# -------------------------------------------- #
def write_response(self, response):
try:
keep_alive = self.parser.should_keep_alive() \
and not self.signal.stopped
def attempt_write(_response):
self.transport.write(
response.output(
_response.output(
self.request.version, keep_alive, self.request_timeout))
try:
keep_alive = (self.parser.should_keep_alive()
and not self.signal.stopped)
try:
# If we already have an HTTPResponse object this should be
# as fast as ever
attempt_write(response)
except AttributeError:
try:
# A performant way to check if we have a list or dict
# Both list and dict contain a `clear` function
response.clear
attempt_write(json(response))
except AttributeError:
attempt_write(text(str(response)))
if not keep_alive:
self.transport.close()
else:

View File

@ -1,4 +1,7 @@
from random import choice
from json import loads as json_loads, JSONDecodeError
import pytest
from sanic import Sanic
from sanic.response import HTTPResponse
@ -16,3 +19,49 @@ def test_response_body_not_a_string():
request, response = sanic_endpoint_test(app, uri='/hello')
assert response.text == str(random_num)
def test_json():
"""Tests the smart handling of dicts for handlers"""
app = Sanic('test_json')
@app.route('/')
async def handler(request):
return {"test": True}
request, response = sanic_endpoint_test(app)
try:
results = json_loads(response.text)
except JSONDecodeError:
pytest.fail(
"Expected JSON response but got '{}'".format(response))
assert results.get('test') is True
def test_text():
"""Tests the smart handling of strings for handlers"""
app = Sanic('test_text')
@app.route('/')
async def handler(request):
return 'Hello'
request, response = sanic_endpoint_test(app)
assert response.text == 'Hello'
def test_int():
"""Tests the smart handling of ints for handlers"""
app = Sanic('test_int')
random_int = choice(range(0, 10000))
@app.route('/')
async def handler(request):
return random_int
request, response = sanic_endpoint_test(app)
assert response.text == str(random_int)