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):
Actual Behavior
/api/v1/my_resource and /api/v1/my_resource_functional respond correctly.
/api/v1/my_resource_problem stalls 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().
When using a middleware that performs an asynchronous operation, the endpoint
/api/v1/my_resource_problemstalls and never responds. In contrast, the endpoints/api/v1/my_resourceand/api/v1/my_resource_functionalwork as expected.Steps to Reproduce
Run the following code:
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_problemExpected 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 asmy_random_number = await simple_database.get_data().Environment
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().