Skip to content

Middleware not preserving state properly #207

@ArthoPacini

Description

@ArthoPacini

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

  1. 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()
  2. 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_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().

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions