Add first-class coroutine PyCoreAsyncCursor to mssql-py-core - #208
Draft
Saurabh Singh (saurabh500) wants to merge 1 commit into
Draft
Conversation
Saurabh Singh (saurabh500)
marked this pull request as ready for review
August 10, 2026 06:38
Copilot started reviewing on behalf of
Saurabh Singh (saurabh500)
August 10, 2026 06:39
View session
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a coroutine-based Python cursor that performs TDS operations without blocking the asyncio event loop.
Changes:
- Adds and registers
PyCoreAsyncCursorandConnection.async_cursor(). - Adds asynchronous client checkout and the required runtime dependency.
- Adds mock and live-server coroutine tests and updates cursor terminology.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
mssql-py-core/Cargo.toml |
Adds the PyO3 async runtime dependency. |
mssql-py-core/src/async_cursor.rs |
Implements the coroutine cursor. |
mssql-py-core/src/connection.rs |
Exposes async_cursor(). |
mssql-py-core/src/lib.rs |
Registers the new Python class. |
mssql-py-core/src/pyclient.rs |
Adds asynchronous client checkout. |
mssql-py-core/tests/rs-only-tests/test_async_cursor_mock.py |
Tests coroutine cursor behavior. |
mssql-py-core/tests/rs-only-tests/test_sync_async_cursor_mock.py |
Corrects default cursor terminology. |
mssql-py-core/tests/test_async_cursor_integration.py |
Verifies live-server non-blocking behavior. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| &self, | ||
| py: Python<'py>, | ||
| query: String, | ||
| params: Option<Vec<Py<PyAny>>>, |
Comment on lines
+268
to
+270
| let taken = { | ||
| let mut guard = cell.lock().map_err(|_| poisoned())?; | ||
| std::mem::replace(&mut *guard, PyClient::Transitioning) |
Saurabh Singh (saurabh500)
marked this pull request as draft
August 10, 2026 06:49
Saurabh Singh (saurabh500)
marked this pull request as ready for review
August 10, 2026 07:40
Saurabh Singh (saurabh500)
marked this pull request as draft
August 10, 2026 13:28
Add PyCoreAsyncCursor, a genuine asyncio coroutine cursor built on pyo3-async-runtimes future_into_py. execute/fetchone/fetchmany/fetchall/ close return awaitables that drive the TDS I/O on the connection's tokio runtime with no block_on on the coroutine path. The !Send client is checked out of the shared cell and the guard dropped before .await, so the Python event loop stays free during fetches. Strictly additive: the default PyCoreCursor and opt-in PyCoreSyncCursor are byte-identical to their prior form. Also scrubs stale 'async cursor' doc labels now that a real coroutine cursor exists. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: e2c378f8-3ba1-4b48-9ebe-5a4ea2bd2761
Saurabh Singh (saurabh500)
force-pushed
the
dev/saurabh/l7-async-cursor
branch
from
August 10, 2026 21:17
dbee5b3 to
0fbfb5e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
PyCoreAsyncCursor, a genuineasynciocoroutine cursor formssql-py-core, built onpyo3-async-runtimesfuture_into_py. This is a correctness/architecture change (a real non-blocking coroutine cursor), not a performance win.execute/fetchone/fetchmany/fetchall/closeeach return a Python awaitable. The TDS I/O is driven on the connection's own tokio runtime and the coroutine.awaits the resulting join handle — there is noblock_onon the coroutine path. The!Sendclient is checked out of the shared cell and the guard is dropped before.await, so the Python event loop stays free while a fetch is in flight.Strictly additive
PyCoreCursor(conn.cursor()) and the opt-in syncPyCoreSyncCursor(conn.sync_cursor()) are byte-identical to their prior form —cursor.rsandsync_cursor.rsare unchanged.conn.async_cursor()→PyCoreAsyncCursor.with_async_clientcheckout helper inpyclient.rs; the shared client cell staysstd::sync::Mutex(no retype needed).Changes (py-core only)
src/async_cursor.rs(new) —PyCoreAsyncCursorcoroutine cursor.src/pyclient.rs—with_async_clientasync checkout helper + honest module doc.src/connection.rs—Connection.async_cursor().src/lib.rs— registerPyCoreAsyncCursor.Cargo.toml— addpyo3-async-runtimes = { version = "0.29", features = ["tokio-runtime"] }.WAITFOR-based non-blocking proof.Non-blocking proof
block_onon theasync_cursor.rscoroutine path (I/O is spawned on the connection runtime; the coroutine awaits the join handle).test_async_cursor_yields_to_event_loop— a concurrent ticker advances while a fetch is awaited (mock answers in µs, so this asserts the weaker "yields at least once").test_async_cursor_integration.py— a concurrent 10ms ticker racks up ticks during a server-sideWAITFOR DELAY '00:00:02'inside the coroutine'sawait.Notes
block_onpath — this is pure coroutine-plumbing overhead on a zero-latency backend, not representative of real network I/O where the overhead is negligible and concurrency dominates.mssql-py-coreCargo.lockis gitignored; the new dep resolves under the--frozenpy-core clippy/test leg locally.Part of the sans-I/O native stack - see cover PR #189 for the stack-level summary and tracked debt.