Concurrent access exception (sqlalchemy asyncio)
See original GitHub issueDescribe 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:
- Created 2 years ago
- Comments:10 (5 by maintainers)
Top 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 >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I like this idea.
Yes. Brain fart. I meant response, which as you mentioned defaults to 60s.