DBIO
view release on metacpan or search on metacpan
docs/adr/0030-async-explicit-per-connection-mode.md view on Meta::CPAN
## Consequences
- **Removed:** `async_fallback` and its auto-chain (0029); `async_backend` as a
per-class auto-default (0028); the always-on silent degrade as the default
behaviour of `*_async` (0014) â it survives only as the explicit `immediate`
mode.
- **Kept:** the universal `*_async` API surface (0014); the `DBIO::Storage::Async`
contract and `DBIO::Future` duck-type; `PoolBase`; the embedded-backend concept
(0028). `future_class` still comes from the live backend.
- **Core changes:** a mode registry + per-connection resolver on
`DBIO::Storage::DBI` (reading `{ async => ... }`); `DBIO::Storage::Async` made
concrete with seam hooks; `PoolBase` readiness-gating default. No event-loop
dependency added to core. Fully mock-testable (`DBIO::Test::Storage` extends
`DBIO::Storage::DBI`): registry resolution, three modes side by side under mock,
unavailable-mode croak, `*_async`-on-sync croak.
- **Driver/add-on changes (thin):** `dbio-async` provides only the abstract
Future::IO base `DBIO::Async::Storage` â `future_io` is convention-resolved per
driver (`DBIO::X::Storage::Async`), not registered generically (karr #65);
`dbio-postgresql-ev`/`dbio-mysql-ev`
keep only EV transport seams + DB-specifics + register `ev`;
`dbio-postgresql`/`dbio-mysql` register the `ev` mapping (no auto-default);
`dbio-forked` registers `forked`. The MySQL-EV `connection()`/`storage_type`
hijack is removed (it contradicts the inert-component model).
- **Extension storage classes** (schema components that set `storage_type` to a
driver-storage subclass: AGE, PostGIS) run `future_io` through the nearest
parent adapter found by the convention's MRO walk (karr #67). Extension-
*specific* async API (e.g. AGE `cypher_async`) lives in the extension dist as
a conventionally-named adapter subclass and additionally requires connection
actions (`on_connect_do`/`on_connect_call`) to fire on pool connections â
a core seam tracked as karr #68; until it lands, pool connections silently
skip session setup, which is also a sync/async divergence for ordinary
users of `on_connect_*`.
- **`dbio-ev` is deliberately NOT created** (YAGNI). After the core lift, too
little shared EV code remains to justify its own dist; revisit if that changes.
- **Migration:** `async_backend('DBIO::Foo::Async::Storage')` on a storage class â
`connect(..., { async => '<mode>' })` at the call site. Driver-specific
async-only features (`listen`/`notify`/`pipeline`/`copy_in`) remain reached via
`$schema->storage->async->...` on the chosen instance.
- **Scope boundary â storage-level only (this increment).** Only the six
*storage-level* `$storage->*_async` are made explicit (croak on a sync
instance). The *ResultSet/Row* `*_async` (`all_async`/`first_async`/
`single_async`/`count_async`/`create_async`) are NOT touched: they still run the
sync op and wrap it in `future_class`, degrading silently even on a sync
instance. So after this increment `$storage->select_async` croaks on a sync
instance while `$rs->all_async` does not â a deliberate, temporary asymmetry
that the RS/Row real-async work (below) closes by routing RS `*_async` through
the storage backend.
## Future architecture work (tracked cross-repo, not here)
- **dbio-async / dbio-postgresql-ev / dbio-mysql-ev**: collapse to transport-only
over the core orchestration; register their mode. karr tickets on their boards.
- **dbio-postgresql / dbio-mysql**: register the `ev` mode mapping; drop the
MySQL-EV `connection()` hijack; reach parity (`deploy_async`, pool readiness).
- **Naming cleanup**: stale `::Async` / `DBIO::EV::Pg` names in core POD and
`DBIO::Manual::Heritage`; `Changes`/README staleness in the add-ons.
- **ResultSet/Row real async** (carried over from the earlier async ADRs): route RS `*_async`
through the storage backend with async row inflation and prefetch/collapse
parity. Its own ADR when taken up.
- **dbio-postgresql-age**: `DBIO::PostgreSQL::Age::Storage::Async` with
`cypher_async` (age board #5) â blocked on core #68 (pool on_connect seam).
## Relationship to other ADRs
- **0028 (class-declared embedded backend) and 0029 (forked auto-fallback) â
removed.** Both are fully replaced by this ADR and have been deleted from
`docs/adr/`; their still-relevant rationale is folded into the Context and
Decision above (why an auto-fallback is a footgun â §Context.1; why the embedded
backend belongs in the storage instance, now chosen per connection rather than
per class â §Decision.1). Git history preserves the originals.
- **0014 â binding/degrade superseded, API kept.** `*_async` stays universal and
the contract/`PoolBase` tier stand; the always-on silent degrade becomes the
explicit `immediate` mode, and `*_async` on a sync instance now croaks instead
of degrading silently. The `DBIO::Test::Future` production-default smell is now
doubly resolved: the class is renamed to `DBIO::Future::Immediate`, and it is
reached only via the named `immediate` mode. 0014's Status is
updated to "superseded in part by 0030".
( run in 1.721 second using v1.01-cache-2.11-cpan-5e09290becf )