NAME

DBIO::Storage::Async::PipelineContext - Generic pinned-connection context for async pipeline batches

VERSION

version 0.900004

DESCRIPTION

The batch context handed to the coderef of "pipeline" in DBIO::Storage::Async. Pipeline mode is per-connection state: a statement is only batched if it is sent on the very connection the scaffold put into pipeline mode. This context is what makes that structural instead of advisory -- it carries the bracketed connection and routes every CRUD call through the storage's shared _run_crud_pinned builder onto it, exactly as DBIO::Storage::Async::TransactionContext does for the pinned transaction connection (dbio-async ADR 0002 / ADR 0003).

Without it, an *_async call inside the batch coderef would go through the pooled path and take a different connection out of the pool -- running outside the bracket, unbatched, and at pool_size => 1 only after the pipeline has released. The statements would still execute; the round-trip economy the batch was written for would silently not happen.

The context is only valid for the synchronous run of the batch coderef: once the coderef returns, the scaffold invalidates the context, syncs, exits pipeline mode and releases the connection. A query issued on the context past that point throws a DBIO::Exception (pipeline context is no longer active) instead of reaching a connection that is back in the pool.

ATTRIBUTES

storage

The parent DBIO::Storage::Async instance.

pipeline_conn

The connection the batch is bracketed on, for the duration of the batch coderef.

pool

Shortcut to $self->storage->pool. It asks the storage each time, so it is the storage's pool as it stands now, not a record of where "pipeline_conn" came from: after the storage was disconnected it is another pool, and with a transport that builds its pool lazily, calling it builds one. The batch does not go through it -- "pipeline" in DBIO::Storage::Async hands "pipeline_conn" back to the pool it acquired it from.

future_class

Shortcut to $self->storage->future_class -- the batch coderef needs it to build the aggregate Future it hands back ($ctx->future_class->needs_all(@futures)).

in_txn

Always false -- a pipeline batch is not a transaction. Bracketing a batch issues no BEGIN; each statement in it commits on its own unless the caller opened a transaction itself.

METHODS

new

my $ctx = DBIO::Storage::Async::PipelineContext->new(
    storage       => $storage,
    pipeline_conn => $conn,
);

Creates a new pipeline context around the bracketed connection. Requires storage and pipeline_conn.

_context_active

True while the batch coderef is running synchronously; false once the "pipeline" in DBIO::Storage::Async scaffold has invalidated the context (it does so the instant the coderef returns, before the pipeline sync). A context-bound DBIO::ResultSet/DBIO::Row/DBIO::ResultSetColumn consults this before routing an *_async op onto the context and refuses loudly rather than silently re-issuing on a pooled connection once it is false -- the window is exactly ADR 0003's "valid only for the synchronous run of the batch coderef" (ADR 0045).

_query_async

Executes a raw statement on the bracketed connection through "_query_async_pinned" in DBIO::Storage::Async, so it is batched onto the pipeline rather than sent on a freshly acquired pooled connection.

_track_statement

return $batch->_track_statement($future);

Keep the Future of a statement this context hands out, and return it. The scaffold ("_pipeline_on_conn" in DBIO::Storage::Async) waits for every kept statement before the connection goes back, and fails the ones still open with the batch's error when the batch fails. A pending Future is returned behind a gate of its own: whichever is answered first -- the transport or the scaffold -- settles it, and the other finds it settled and does nothing. A synchronous throw from one of the CRUD methods is not tracked: nothing was handed out.

select_async

select_single_async

insert_async

update_async

delete_async

Same arguments and resolution shapes as the storage methods of the same names ("select_async" in DBIO::Storage::Async etc.), but every statement runs on the bracketed "pipeline_conn" through the storage's shared pinned CRUD builder, so it is batched instead of taking a separate pooled connection. Each throws a DBIO::Exception once the context is no longer active or its ownership cannot be proven.

select

select_single

insert

update

delete

Deliberately refused: each croaks, naming the *_async form to use instead. A batched statement only resolves at the pipeline sync, which runs after the batch coderef has returned, so blocking on it inside the coderef would deadlock.

sql_maker

debug

Delegate to the parent storage's sql_maker and debug.

AUTHOR

DBIO & DBIx::Class Authors

COPYRIGHT AND LICENSE

Copyright (C) 2026 DBIO Authors Portions Copyright (C) 2005-2025 DBIx::Class Authors Based on DBIx::Class, heavily modified.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.