Repository navigation
Conversation
fnc12
force-pushed
the
feature/async-storage
branch
3 times, most recently
from
September 6, 2026 15:53
fb465ed to
ae1292d
Compare
`async_storage`, available where SQLITE_ORM_ASYNC_SUPPORTED is defined (Linux, C++20 coroutines, GCC 13+ or Clang, x86_64/aarch64), mirrors the public interface of storage_t with `co_await`: - every operation runs the unchanged synchronous storage code on a fiber (stackful coroutine, inline asm for x86_64/aarch64) so that sqlite3_step() can suspend inside file I/O without blocking the thread - a single-threaded scheduler over io_uring on raw syscalls (no liburing) - an SQLite VFS wrapping "unix" that routes xRead/xWrite/xSync/xSleep through the scheduler, every operation awaited in order - C++20 front-end: task<T>, io_context, when_all, io_pool (M:N) - one storage is one connection, opened lazily and kept open; operations from several coroutines are queued in order, prepared statements always run on the connection they were prepared on - make_async_storage(io, filename, args...) mirrors make_storage; the VFS is injected through connection_control, nothing global changes Part of the main amalgamation (dev/async/ via config.json), inert on other platforms and on GCC 11/12, which miscompile temporaries living across a suspension in a co_await expression. Tests in tests/async, docs in docs/async.md. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hk4PTDLH4bDkSxx7Y6A384
fnc12
force-pushed
the
feature/async-storage
branch
from
September 6, 2026 17:00
ae1292d to
23273f2
Compare
This branch has not been deployed
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
async_storage: the ordinarystoragedriven withco_await, with real asynchronous file I/O underneath (io_uring). The synchronous ORM code is not modified;async_storagemirrors the public interface ofstorage_t.How it works
dev/async/context_switch.h,fiber.h), sosqlite3_step()can suspend in the middle of a page read without blocking the thread.unix(dev/async/async_vfs.h) routesxRead/xWrite/xSync/xSleepto a single-threaded scheduler over io_uring (scheduler.h,io_uring_engine.h, raw syscalls, no liburing). Locking, WAL shared memory and open/delete stay with the wrapped VFS. Every operation is awaited in order (writes are not batched: measured on one connection, batching cost 30% of commit throughput because every read had to wait for queued writes, while awaited writes match the synchronous path). Memory-mapped I/O is disabled for these connections.connection_control(#1392 : Add support for SQLite VFS and open mode flags #1393); nothing global is registered.task<T>,io_context,when_all,io_poolfor M:N, one class per header.async_storage<Storage>(async_storage.h): one connection, opened lazily and kept open. Like a network connection in an asynchronous client, requests do not block the thread but execute one after another; operations from several coroutines are queued in order, so prepared statements always run on the connection they were prepared on.run(function)is the primitive; CRUD,get_all,select,with, aggregates,prepare/execute, schema functions,transaction/savepoint, connection information and backups are mirrored, with arguments moved into the operation. Functions without I/O (filename,vfs_name,open_mode,dump,interrupt,is_opened) are plain calls.Scope
Gated by
SQLITE_ORM_ASYNC_SUPPORTED: Linux, C++20 coroutines, GCC 13 or newer or Clang, x86_64 or aarch64; part of the main amalgamation (dev/async/inconfig.json) and inert elsewhere. GCC 11 and 12 are excluded because they miscompile temporaries that live across a suspension in aco_awaitexpression (co_await storage.insert(User{...})), verified with a minimal reproduction against GCC 11.4, 12.5, 13.4, 14.3, 15.2 and Clang 14. If the kernel refuses io_uring at runtime theio_contextconstructor throws;io_uring_available()tells in advance and the tests skip in that case.Measured on a 2.6 GB WAL database on NVMe (random point lookups, 4 KB pages): one connection matches the synchronous storage (cold cache: 13.3k vs 13.4k lookups/s; warm cache: 405k vs 467k, the fiber switch and the io_uring syscall cost ~0.3 µs per read; a writer committing with
synchronous=FULL: 670 vs 669 commits/s), while the thread stays free during the wait. With 32 connections on one thread the same workload does ~200k lookups/s cold.Testing
tests/async/async_storage_tests.cpp(Catch2): factory and VFS injection, lazy open, userconnection_control, CRUD, aggregates, prepared statements, transactions and savepoints, schema and connection information, backups, queued operations from several coroutines,io_pool../build/tests/unit_tests -# "[#async_storage_tests]".Open points
iterate<T>()is not exposed as an asynchronous generator; iterate insiderun.xOpen,xFileSizeandxTruncateremain synchronous.🤖 Generated with Claude Code
https://claude.ai/code/session_01Hk4PTDLH4bDkSxx7Y6A384