Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Concurrency issues when using FastAPI #101

Open
2 tasks done
juangesino opened this issue May 30, 2024 · 6 comments
Open
2 tasks done

Bug: Concurrency issues when using FastAPI #101

juangesino opened this issue May 30, 2024 · 6 comments
Labels
bug Something isn't working

Comments

@juangesino
Copy link

Describe the bug

When trying to use SurrealDB in a FastAPI project, whenever I get concurrent requests that hit the database, the application raises the following exception:

RuntimeError: cannot call recv while another coroutine is already waiting for the next message

After that, the server becomes unresponsive and the only solution is to restart.

Steps to reproduce

Assuming you have docker installed:

  1. Clone this repository: git clone https://github.com/juangesino/surrealdb-fastapi-concurrency-error
  2. Go to the repository source: cd surrealdb-fastapi-concurrency-error
  3. Build and start the docker containers: make build or docker-compose -f docker-compose.yml up --build --force-recreate
  4. Run the sequential test (this one should work fine): make sequential or docker exec -it surreal-demo-server-1 python demo_sequential.py
  5. Run the concurrent test (this one will fail): make concurrent or docker exec -it surreal-demo-server-1 python demo_concurrent.py

You should get the exception mentioned before:

RuntimeError: cannot call recv while another coroutine is already waiting for the next message

The server will not respond after that and you will have to restart it.

Expected behaviour

The Python SDK should be able to handle concurrent requests.

SurrealDB version

surrealdb/surrealdb:v1.5.0 (docker)

surrealdb.py version

0.3.2 for python:3.11.4-slim-buster (docker)

Contact Details

https://discord.com/channels/902568124350599239/1245739617525960778/1245768819553603666

Is there an existing issue for this?

  • I have searched the existing issues

Code of Conduct

  • I agree to follow this project's Code of Conduct
@juangesino juangesino added the bug Something isn't working label May 30, 2024
@MarcusVirg
Copy link

MarcusVirg commented Jun 1, 2024

I have the same issue when using FastAPI. I am also seeing an issue where a request to the database actually returns a previous query result causing serialization issues with my project. I haven't been able to recreate consistently but I imagine this is an issue related to socket polling happening out of order. It really makes this library unusable in production APIs at the moment.

@shkr
Copy link

shkr commented Jun 19, 2024

Same issue

@krikkiteer
Copy link

same issue.. when using within litestar, or plain python-service.

@Anton-2
Copy link

Anton-2 commented Sep 8, 2024

As currently written, this library cannot handle concurrent queries over websocket. It expects the response for a command to follow immediately, in order. If you issue two commands before the first response, the responses may be out of order and this library will be confused.

I've got a POC for a very simple asyncio wrapper around the websocket rpc. Tested on surrealdb 1.5.4 and 2.0.0 beta.

It allows to send raw commands (use, signin, ...), perform queries and live queries.

It only needs websockets and orjson (for speed, but could use standard json instead).

see: https://gist.github.com/Anton-2/2f2919d402a95823a22d378455ec9ab3

Tell me if it works for you, I'll try to create a real library if there's enough interest.

@shkr
Copy link

shkr commented Sep 9, 2024 via email

@Anton-2
Copy link

Anton-2 commented Sep 20, 2024

Feel free to try : surrealpy
Documentation and exemple to come, but it follows mostly the official driver.

usage in FastAPI:

db = SurrealDB()

@asynccontextmanager
async def lifespan(app: FastAPI):
    await db.connect()
    await db.signin({"user": "root", "pass": "root"})
    await db.use("default", "default")

    yield

    await db.close()


app = FastAPI(lifespan=lifespan)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants