socketify.py
                                
                                 socketify.py copied to clipboard
                                
                                    socketify.py copied to clipboard
                            
                            
                            
                        ASGI not working properly, CFFI life cycle is wrong.
Describe the bug I can crash the server using the below app, it happens evertime I run the second wrk command, and the stacktrace is:
❯ python main_socketify.py
ERROR:root:Uncaught Exception: {'message': 'RequestTask exception was never retrieved', 'exception': RuntimeError('aclose(): asynchronous generator is already running'), 'future': <RequestTask finished name='socketify.py-request-task' coro=<<async_generator_athrow without __name__>()> exception=RuntimeError('aclose(): asynchronous generator is already running')>}
ERROR:root:Uncaught Exception: {'message': 'RequestTask exception was never retrieved', 'exception': RuntimeError('aclose(): asynchronous generator is already running'), 'future': <RequestTask finished name='socketify.py-request-task' coro=<<async_generator_athrow without __name__>()> exception=RuntimeError('aclose(): asynchronous generator is already running')>}
ERROR:root:Uncaught Exception: {'message': 'RequestTask exception was never retrieved', 'exception': RuntimeError('aclose(): asynchronous generator is already running'), 'future': <RequestTask finished name='socketify.py-request-task' coro=<<async_generator_athrow without __name__>()> exception=RuntimeError('aclose(): asynchronous generator is already running')>}
ERROR:root:Uncaught Exception: {'message': 'RequestTask exception was never retrieved', 'exception': RuntimeError('aclose(): asynchronous generator is already running'), 'future': <RequestTask finished name='socketify.py-request-task' coro=<<async_generator_athrow without __name__>()> exception=RuntimeError('aclose(): asynchronous generator is already running')>}
ERROR:root:Uncaught Exception: {'message': 'RequestTask exception was never retrieved', 'exception': RuntimeError('aclose(): asynchronous generator is already running'), 'future': <RequestTask finished name='socketify.py-request-task' coro=<<async_generator_athrow without __name__>()> exception=RuntimeError('aclose(): asynchronous generator is already running')>}
ERROR:root:Uncaught Exception: {'message': 'RequestTask exception was never retrieved', 'exception': RuntimeError('aclose(): asynchronous generator is already running'), 'future': <RequestTask finished name='socketify.py-request-task' coro=<<async_generator_athrow without __name__>()> exception=RuntimeError('aclose(): asynchronous generator is already running')>}
ERROR:root:Uncaught Exception: {'message': 'RequestTask exception was never retrieved', 'exception': RuntimeError('aclose(): asynchronous generator is already running'), 'future': <RequestTask finished name='socketify.py-request-task' coro=<<async_generator_athrow without __name__>()> exception=RuntimeError('aclose(): asynchronous generator is already running')>}
ERROR:root:Uncaught Exception: {'message': 'RequestTask exception was never retrieved', 'exception': RuntimeError('aclose(): asynchronous generator is already running'), 'future': <RequestTask finished name='socketify.py-request-task' coro=<<async_generator_athrow without __name__>()> exception=RuntimeError('aclose(): asynchronous generator is already running')>}
ERROR:root:Uncaught Exception: {'message': 'RequestTask exception was never retrieved', 'exception': RuntimeError('aclose(): asynchronous generator is already running'), 'future': <RequestTask finished name='socketify.py-request-task' coro=<<async_generator_athrow without __name__>()> exception=RuntimeError('aclose(): asynchronous generator is already running')>}
ERROR:root:Uncaught Exception: {'message': 'RequestTask exception was never retrieved', 'exception': RuntimeError('aclose(): asynchronous generator is already running'), 'future': <RequestTask finished name='socketify.py-request-task' coro=<<async_generator_athrow without __name__>()> exception=RuntimeError('aclose(): asynchronous generator is already running')>}
ERROR:root:Uncaught Exception: {'message': 'RequestTask exception was never retrieved', 'exception': RuntimeError('aclose(): asynchronous generator is already running'), 'future': <RequestTask finished name='socketify.py-request-task' coro=<<async_generator_athrow without __name__>()> exception=RuntimeError('aclose(): asynchronous generator is already running')>}
ERROR:root:Uncaught Exception: {'message': 'RequestTask exception was never retrieved', 'exception': RuntimeError('aclose(): asynchronous generator is already running'), 'future': <RequestTask finished name='socketify.py-request-task' coro=<<async_generator_athrow without __name__>()> exception=RuntimeError('aclose(): asynchronous generator is already running')>}
ERROR:root:Uncaught Exception: {'message': 'RequestTask exception was never retrieved', 'exception': RuntimeError('aclose(): asynchronous generator is already running'), 'future': <RequestTask finished name='socketify.py-request-task' coro=<<async_generator_athrow without __name__>()> exception=RuntimeError('aclose(): asynchronous generator is already running')>}
ERROR:root:Uncaught Exception: {'message': 'RequestTask exception was never retrieved', 'exception': RuntimeError('aclose(): asynchronous generator is already running'), 'future': <RequestTask finished name='socketify.py-request-task' coro=<<async_generator_athrow without __name__>()> exception=RuntimeError('aclose(): asynchronous generator is already running')>}
ERROR:root:Uncaught Exception: {'message': 'RequestTask exception was never retrieved', 'exception': RuntimeError('aclose(): asynchronous generator is already running'), 'future': <RequestTask finished name='socketify.py-request-task' coro=<<async_generator_athrow without __name__>()> exception=RuntimeError('aclose(): asynchronous generator is already running')>}
ERROR:root:Uncaught Exception: {'message': 'RequestTask exception was never retrieved', 'exception': RuntimeError('aclose(): asynchronous generator is already running'), 'future': <RequestTask finished name='socketify.py-request-task' coro=<<async_generator_athrow without __name__>()> exception=RuntimeError('aclose(): asynchronous generator is already running')>}
Fatal Python error: b_from_handle: ffi.from_handle() detected that the address passed points to garbage. If it is really the result of ffi.new_handle(), then the Python object has already been garbage collected
Python runtime state: initialized
Thread 0x00007f61d65ff6c0 (most recent call first):
  File "/home/lotso/.asdf/installs/python/3.11.3/lib/python3.11/threading.py", line 320 in wait
  File "/home/lotso/.asdf/installs/python/3.11.3/lib/python3.11/queue.py", line 171 in get
  File "/home/lotso/.cache/pypoetry/virtualenvs/litestar-34KzF20t-py3.11/lib/python3.11/site-packages/picologging/handlers.py", line 613 in dequeue
  File "/home/lotso/.cache/pypoetry/virtualenvs/litestar-34KzF20t-py3.11/lib/python3.11/site-packages/picologging/handlers.py", line 664 in _monitor
  File "/home/lotso/.asdf/installs/python/3.11.3/lib/python3.11/threading.py", line 975 in run
  File "/home/lotso/.asdf/installs/python/3.11.3/lib/python3.11/threading.py", line 1038 in _bootstrap_inner
  File "/home/lotso/.asdf/installs/python/3.11.3/lib/python3.11/threading.py", line 995 in _bootstrap
Current thread 0x00007f61da631b80 (most recent call first):
  File "/home/lotso/.cache/pypoetry/virtualenvs/litestar-34KzF20t-py3.11/lib/python3.11/site-packages/cffi/api.py", line 544 in from_handle
  File "/home/lotso/.cache/pypoetry/virtualenvs/litestar-34KzF20t-py3.11/lib/python3.11/site-packages/socketify/asgi.py", line 15 in asgi_on_abort_handler
  File "/home/lotso/.cache/pypoetry/virtualenvs/litestar-34KzF20t-py3.11/lib/python3.11/site-packages/socketify/uv.py", line 89 in run_nowait
  File "/home/lotso/.cache/pypoetry/virtualenvs/litestar-34KzF20t-py3.11/lib/python3.11/site-packages/socketify/loop.py", line 95 in _keep_alive
  File "/home/lotso/.asdf/installs/python/3.11.3/lib/python3.11/asyncio/events.py", line 80 in _run
  File "/home/lotso/.asdf/installs/python/3.11.3/lib/python3.11/asyncio/base_events.py", line 1922 in _run_once
  File "/home/lotso/.asdf/installs/python/3.11.3/lib/python3.11/asyncio/base_events.py", line 607 in run_forever
  File "/home/lotso/.cache/pypoetry/virtualenvs/litestar-34KzF20t-py3.11/lib/python3.11/site-packages/socketify/loop.py", line 125 in run
  File "/home/lotso/.cache/pypoetry/virtualenvs/litestar-34KzF20t-py3.11/lib/python3.11/site-packages/socketify/socketify.py", line 3379 in run
  File "/home/lotso/.cache/pypoetry/virtualenvs/litestar-34KzF20t-py3.11/lib/python3.11/site-packages/socketify/asgi.py", line 750 in run
  File "/home/lotso/.cache/pypoetry/virtualenvs/litestar-34KzF20t-py3.11/lib/python3.11/site-packages/socketify/asgi.py", line 836 in run_task
  File "/home/lotso/.cache/pypoetry/virtualenvs/litestar-34KzF20t-py3.11/lib/python3.11/site-packages/socketify/asgi.py", line 852 in run
  File "/home/lotso/PycharmProjects/litestar/main_socketify.py", line 8 in <module>
Extension modules: _cffi_backend, msgspec._core, pydantic.typing, pydantic.errors, pydantic.version, pydantic.utils, pydantic.class_validators, pydantic.config, pydantic.color, pydantic.datetime_parse, pydantic.validators, pydantic.networks, pydantic.types, pydantic.json, pydantic.error_wrappers, pydantic.fields, pydantic.parse, pydantic.schema, pydantic.main, pydantic.dataclasses, pydantic.annotated_types, pydantic.decorator, pydantic.env_settings, pydantic.tools, pydantic, yaml._yaml, multidict._multidict, greenlet._greenlet, picologging._picologging (total: 29)
[1]    105178 IOT instruction  python main_socketify.py
To Reproduce Steps to reproduce the behavior:
run this app in te.py:
from typing import Annotated
import msgspec
from attr import define, field
from attr.validators import ge, instance_of, lt
from pydantic import BaseModel, ConfigDict, Field
from litestar import Litestar, Request, post
from litestar.enums import RequestEncodingType
from litestar.params import Body
MAX_INT_POSTGRES = 10
@define
class AddProductFormAttrs:
    amount: int = field(validator=[instance_of(int), ge(1), lt(MAX_INT_POSTGRES)])
class AddProductFormPydantic(BaseModel):
    model_config = ConfigDict(arbitrary_types_allowed=True)
    amount: int = Field(ge=1, lt=MAX_INT_POSTGRES)
class AddProductFormMsgspec(msgspec.Struct):
    amount: Annotated[int, msgspec.Meta(lt=MAX_INT_POSTGRES, ge=1)]
@post(path="/form/attrs")
async def form_attrs(
    request: Request, data: Annotated[AddProductFormAttrs, Body(media_type=RequestEncodingType.URL_ENCODED)]
) -> int:
    return data.amount
@post(path="/form/pydantic")
async def form_pydantic(
    request: Request, data: Annotated[AddProductFormPydantic, Body(media_type=RequestEncodingType.URL_ENCODED)]
) -> int:
    return data.amount
@post(path="/form/msgspec")
async def form_msgspec(
        request: Request, data: Annotated[AddProductFormMsgspec, Body(media_type=RequestEncodingType.URL_ENCODED)]
) -> int:
    return data.amount
app = Litestar(route_handlers=[form_attrs, form_pydantic, form_msgspec], debug=True)
- run the app using :+1:
from socketify import ASGI
from te import app
if __name__ == "__main__":
    ASGI(app, lifespan=False).listen(9000).run(1)
- run wrk twice:
- docker run --rm -v './':/data williamyeh/wrk -t8 -c128 -d5 -s post.lua http://yourserver:9000/form/msgspec where post.lua is
wrk.method = "POST"
wrk.body   = "amount=1"
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
Expected behavior it should not crash
ASGI is being rewritten is too broken right now, WSGI is in a better place but can be way better.