-
-
Notifications
You must be signed in to change notification settings - Fork 60
Description
When using a middleware that performs an asynchronous operation, the endpoint /api/v1/my_resource_problem stalls and never responds. In contrast, the endpoints /api/v1/my_resource and /api/v1/my_resource_functional work as expected.
Steps to Reproduce
-
Run the following code:
from socketify import App, AppOptions, OpCode, CompressOptions, middleware, AppListenOptions import faulthandler import aiosqlite faulthandler.enable() class SimpleDatabase: def __init__(self, db_path: str = ":memory:"): self.db_path = db_path async def get_data(self): async with aiosqlite.connect(self.db_path) as db: async with db.execute("SELECT RANDOM()") as cursor: row = await cursor.fetchone() return row[0] if row else None simple_database = SimpleDatabase() async def problem_middleware(res, req, data=None): my_random_number = await simple_database.get_data() return {"hello":"world"} async def functional_middleware(res, req, data=None): return {"hello":"world"} async def post_data(res, req, data=None): data = await res.get_json() print(data) res.cork_end({"success": True}) def make_app(app): app.post("/api/v1/my_resource", post_data) app.post("/api/v1/my_resource_problem", middleware(problem_middleware, post_data)) app.post("/api/v1/my_resource_functional", middleware(functional_middleware, post_data)) from typing import Dict, Any, Callable, List, Optional, Union, Literal app = App() make_app(app) app.listen(AppListenOptions(port=5555, host="0.0.0.0"), lambda config: print(f"Listening on port http://{config.host}:%d now\n" % (config.port))) app.run()
-
Send a POST request with valid JSON data to the following endpoints:
/api/v1/my_resource/api/v1/my_resource_functional/api/v1/my_resource_problem
Expected Behavior
All endpoints should respond with (and print the posted data in the stdout):
{
"success": True
}Actual Behavior
/api/v1/my_resourceand/api/v1/my_resource_functionalrespond correctly./api/v1/my_resource_problemstalls and never replies.
Additional Information
It appears that await res.get_json() enters an infinite loop when a previous middleware performs an asynchronous call, such as my_random_number = await simple_database.get_data().
Environment
- socketify Version: 0.0.31
Note: same behavior happens on data = await res.get_data().
Actually the problem seems to happen inside the .get_data() (it is called from the .get_json().