squeaky-pl / japronto

Screaming-fast Python 3.5+ HTTP toolkit integrated with pipelining HTTP server based on uvloop and picohttpparser.
MIT License
8.62k stars 580 forks source link

After some number of requests, the sever prints 'incomplete body'. #172

Open allComputableThings opened 4 years ago

allComputableThings commented 4 years ago

server.py

from japronto import Application
from japronto.request import HttpRequest

def hello(request: HttpRequest):
    r = request
    # print(r.body)
    body = r.body
    return r.Response(text=body)

app = Application()
app.router.add_route('/ping', hello)
app.run(debug=True, port=5000)

client.py

import asyncio
import time

import aiohttp
NPARALLEL = 1000
aiohttp.TCPConnector(limit=1000)  # 480 requests with 1 connection, adding more not helping

async def fetch(session, i):
    # print(f"{i}")
    async with session.post("http://127.0.0.1:5000/ping", data=f"MSG {i}") as response:
        result = response
        # print(result)
        assert result.status==200
        data = await(result.content.read())
        # print(data.decode())

async def fetch_all(loop):
    async with aiohttp.ClientSession(loop=loop) as session:
        tstart = time.time()
        # 200 requests per second
        results = await asyncio.gather(*[fetch(session, i)
                                         for i in range(NPARALLEL)],
                                       # return_exceptions=True
                                       )
        dur = time.time()-tstart
        print(f"Dur: {dur}s   {NPARALLEL/dur}/sec")

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    # urls = url_list
    loop.run_until_complete(fetch_all(loop))

Gives:

Traceback (most recent call last):
  File "/home/sir/ailive/livebetter/phy_nlp/phy_nlp/server/japronto_server.py", line 9, in hello
    return r.Response(text=body)
TypeError: bad argument type for built-in operation
Fatal error on transport TCPTransport
protocol: <cprotocol.Protocol object at 0x263f440>
transport: <TCPTransport closed=False reading=False 0x2641090>
Traceback (most recent call last):
  File "uvloop/handles/stream.pyx", line 829, in uvloop.loop.__uv_stream_on_read_impl
  File "/home/sir/venv/p37_default/lib/python3.7/site-packages/japronto/app/__init__.py", line 104, in error_handler
    return self.default_error_handler(request, exception)
  File "/home/sir/venv/p37_default/lib/python3.7/site-packages/japronto/app/__init__.py", line 86, in default_error_handler
    text=tb if self._debug else 'Internal Server Error')
RuntimeError: Request.Response can only be called once per request
incomplete_body
incomplete_body
incomplete_body
incomplete_body
incomplete_body
incomplete_body
incomplete_body
incomplete_body
incomplete_body
incomplete_body
incomplete_body
incomplete_body
incomplete_body
incomplete_body
incomplete_body
allComputableThings commented 4 years ago

Probably related to: https://github.com/squeaky-pl/japronto/issues/6

junbaibai0719 commented 3 years ago

text expect a string not byte. So Request.Response can't return. u can use r.text instead of r.body.