question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Concurrent access exception (sqlalchemy asyncio)

See original GitHub issue

Describe the bug

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/baloneo/PycharmProjects/sanic-learn/venv/lib/python3.8/site-packages/sanic/request.py", line 187, in respond
    response = await self.app._run_response_middleware(
  File "_run_response_middleware", line 22, in _run_response_middleware
    from ssl import Purpose, SSLContext, create_default_context
  File "/home/baloneo/PycharmProjects/sanic-learn/app/__init__.py", line 26, in close_session
    _base_model_session_ctx.reset(request.ctx.session_ctx_token)
RuntimeError: <Token used var=<ContextVar name='session' at 0x7fcebbce4b80> at 0x7fceb99a45c0> has already been used once
[2021-11-03 13:32:36 +0800] [1826175] [ERROR] Exception occurred in one of response middleware handlers
Traceback (most recent call last):
  File "/home/baloneo/PycharmProjects/sanic-learn/venv/lib/python3.8/site-packages/sanic/http.py", line 141, in http1
    await self.protocol.request_handler(self.request)
  File "handle_request", line 100, in handle_request
    "_future_routes",
  File "/home/baloneo/PycharmProjects/sanic-learn/venv/lib/python3.8/site-packages/sanic/response.py", line 122, in send
    await self.stream.send(data, end_stream=end_stream)
  File "http1_response_header", line 70, in http1_response_header
  File "send", line 7, in send
asyncio.exceptions.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/baloneo/PycharmProjects/sanic-learn/venv/lib/python3.8/site-packages/sanic/request.py", line 187, in respond
    response = await self.app._run_response_middleware(
  File "_run_response_middleware", line 22, in _run_response_middleware
    from ssl import Purpose, SSLContext, create_default_context
  File "/home/baloneo/PycharmProjects/sanic-learn/app/__init__.py", line 26, in close_session
    _base_model_session_ctx.reset(request.ctx.session_ctx_token)
RuntimeError: <Token used var=<ContextVar name='session' at 0x7fcebbce4b80> at 0x7fceb990d240> has already been used once


To Reproduce

Follow the tutorial: https://sanicframework.org/en/guide/how-to/orm.html#sqlalchemy

same code



from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import sessionmaker

_base_model_session_ctx = ContextVar("session")


@app.middleware("request")
async def inject_session(request):
    request.ctx.session = sessionmaker(engine, AsyncSession, expire_on_commit=False)()
    request.ctx.session_ctx_token = _base_model_session_ctx.set(request.ctx.session)


@app.middleware("response")
async def close_session(request, response):
    if hasattr(request.ctx, "session_ctx_token"):
        _base_model_session_ctx.reset(request.ctx.session_ctx_token)
        await request.ctx.session.close()

@bp.route('/data', methods=['GET'])
async def get_data(request: Request):
    session: AsyncSession = request.ctx.session
    async with session.begin():
        stmt = select(Data)
        row = await session.execute(stmt)
        for i in row:
            print(i)

    return json({})



using wrk, https://github.com/wg/wrk

➜  /tmp wrk -t5 -d10s -c100 http://127.0.0.1:8000/api/v1/data
Running 10s test @ http://127.0.0.1:8000/api/v1/data
  5 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.05s   187.32ms   1.99s    90.38%
    Req/Sec    23.39     15.98    80.00     61.19%
  715 requests in 10.03s, 67.03KB read
  Socket errors: connect 0, read 0, write 0, timeout 102
Requests/sec:     71.25
Transfer/sec:      6.68KB

Versions

  • OS:Linuxmint 20.2 uma
  • Python:3.8
  • SQLAlchemy:1.4.26
  • Database:MySQL8.0
  • DBAPI (eg: psycopg, cx_oracle, mysqlclient):aiomysql

Additional context

No response

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
ahopkinscommented, Dec 1, 2021

cancel() also accepts a “msg” argument, might it be a good idea for this “message” to be added to places like

I like this idea.

0reactions
ahopkinscommented, Dec 1, 2021

OK this would in theory be a response timeout but per the above doc that defaults to 60 seconds, so unless they are changing that, it’s not possible this particular cancel() is it because their whole test case runs in 10 seconds.

Yes. Brain fart. I meant response, which as you mentioned defaults to 60s.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Asynchronous I/O (asyncio) - SQLAlchemy 1.4 Documentation
The “scopefunc” used by async_scoped_session is invoked an arbitrary number of times within a task, once for each time the underlying ...
Read more >
SQLAlchemy exception while concurrent queries
SQLAlchemy exception while concurrent queries ... It works fine in single process mode, but when I build more than one process, this error...
Read more >
Python, SQLAlchemy, and Concurrency - Better Programming
A guide to concurrent Python and SQLAlchemy. Discusses coroutines, threads, parallelism, concurrency, asyncio, and modern Python language ...
Read more >
Main thread is blocked on concurrent async operations #5581
Typically this involves using asyncio.Lock() to control concurrency. To Reproduce. import asyncio from sqlalchemy.ext.
Read more >
Python Asyncio Part 5 – Mixing Synchronous and ...
To work around this you can construct an object of class concurrent.futures.ProcessPoolExecutor and pass it as the first parameter of run_in_executor , instead ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found