Changes for version 0.900001 - 2026-07-12
- First release. The shared, loop-agnostic async layer for DBIO drivers.
- Storage
- DBIO::Async::Storage, the future_io transport backend subclassing core DBIO::Storage::Async: it inherits the Model-B orchestration (_run_crud / txn_do_async / pipeline, sync ->get fallbacks, connect-info normalisation, AccessBroker wiring) from core (ADR 0030 §4) and supplies only the transport -- Future::IO query execution (_query_async / _query_async_pinned over an isolated watcher seam: _await_conn_ready / _await_query_result over ready_for_read on a driver-supplied socket fd), the Future class, and the connection pool. DB-specific seam hooks croak "Subclass must override" until a driver overrides them.
- future_io resolves a driver's DBIO::Async::Storage subclass by CONVENTION in core (ref($storage) . '::Async'); loading DBIO::Async no longer globally registers future_io on the core base (ADR 0030 refinement, karr #65).
- _query_async / _query_async_pinned shape sql_maker's '?' placeholders into the driver dialect internally via the inherited _transform_sql seam (core #70 WP3, karr #3); the shaping is idempotent on already-shaped SQL (including a '?' inside a quoted literal), so it is safe alongside core's own call-site shaping during the transition. Declares transport_capabilities => ('on_connect_replay'), so an async layer that needs on_connect replay (e.g. AGE) can compose onto this transport instead of silently losing the capability (backed by the pool -> _setup_pool_connection -> _run_pool_connect_statement replay chain, karr #68).
- The poll fd a driver's _conn_fileno returns is wrapped once per connection into a cached filehandle (_conn_poll_fh, dup'd via open '+<&') for Future::IO->poll, and reused by _await_readable. Some Future::IO impls (e.g. IO::Async) mark a future done, and thus run its on_ready close, BEFORE unwatch_io's by fileno; dup-and-close per poll left a closed handle whose fileno came back undef and corrupted the impl's watch table. One stable handle per connection keeps the fileno valid across the whole watch/unwatch cycle. This establishes a documented base assumption: $conn is a hashref, with the poll filehandle cached under a reserved key. karr #25.
- Pool
- DBIO::Async::Pool subclassing core DBIO::Storage::PoolBase with a generalized connection-readiness role: drivers whose connection object is not immediately ready supply it; others short-circuit to done($conn).
- TransactionContext
- DBIO::Async::TransactionContext, a thin subclass of core's generic DBIO::Storage::Async::TransactionContext (ADR 0030 §4): the unified txn_conn accessor / pinned-connection wrapper -- replacing the per-driver txn_pg / txn_mdb names -- now lives in core and is inherited unchanged.
- Dependencies
- The Future / Future::IO requirements live here, not in each driver, so a sync-only driver pulls no async dependencies — installing dbio-async is what turns async on. Future::IO's built-in default impl is IO::Poll; no event loop is a hard require (core ADR 0014).
Documentation
Modules
Shared, loop-agnostic async layer for DBIO drivers
Generic async connection pool for DBIO drivers
Future::IO transport backend for DBIO async storage
Pinned-connection context for dbio-async (future_io) transactions