emmett-framework / granian

A Rust HTTP server for Python applications
BSD 3-Clause "New" or "Revised" License
2.67k stars 79 forks source link

`--opt` in RSGI mode is incompatible with `asyncio.timeout` #323

Open 2-5 opened 3 months ago

2-5 commented 3 months ago

Not sure if this is expected/by-design or not, so I'm reporting it:

import asyncio

async def app(scope, proto):

    async with asyncio.timeout(1):
        await asyncio.sleep(0.1)

    proto.response_str(
        status=200,
        headers=[
            ('content-type', 'text/plain')
        ],
        body=f"Hello, world!"
    )
$ granian --opt --interface rsgi main:app
[ERROR] Application callable raised an exception
Traceback (most recent call last):
  File "main.py", line 5, in app
    async with asyncio.timeout(1):
  File "/usr/lib/python3.11/asyncio/timeouts.py", line 90, in __aenter__
    raise RuntimeError("Timeout should be used inside a task")
RuntimeError: Timeout should be used inside a task

This was quite difficult to track down, maybe a small section could be added to the documentation with a short list of what's known to not work when using --opt

gi0baro commented 3 months ago

@2-5 yeah, I'm sorry about that. I'm actually considering to just drop the --opt option and related code (maybe after deprecating it for a few releases). The actual benefits have become more and more questionable with Python 3.11, and almost every real world application out there seems to rely on variables/stuff dropped by those optimizations.

Just for reference, if you move the timeout into a dedicated coro and await such coro in your app it should work.