DBIO-Async
view release on metacpan or search on metacpan
lib/DBIO/Async/Pool.pm view on Meta::CPAN
sub new {
my ($class, %args) = @_;
my $storage = delete $args{storage};
croak('storage required') unless $storage;
my $self = $class->SUPER::new(%args);
$self->{storage} = $storage;
Scalar::Util::weaken($self->{storage}) if ref $self->{storage};
return $self;
}
sub acquire {
my $self = shift;
return $self->SUPER::acquire->then(sub {
my $conn = shift;
return $self->_await_conn_ready($conn);
});
lib/DBIO/Async/Pool.pm view on Meta::CPAN
my $pool = DBIO::Async::Pool->new(
storage => $storage, # required
conninfo => $conninfo, # or conninfo_provider
size => 10,
on_error => sub { warn $_[0] },
);
Like L<DBIO::Storage::PoolBase/new>, but requires a C<storage> argument
(the L<DBIO::Async::Storage> that owns this pool). The storage reference
is weakened to avoid a cycle (storage holds pool, pool holds storage).
=head2 acquire
Like L<DBIO::Storage::PoolBase/acquire>, but the resolved Future does not
complete until the connection is actually ready for queries. This
correctly handles drivers where connection construction returns before
the async connect finishes (e.g. libpq's C<PQconnectStart>).
Readiness is checked via L</_await_conn_ready>, which delegates to the
Storage's L<DBIO::Async::Storage/_await_conn_ready>.
t/04-bind-release.t view on Meta::CPAN
use strict;
use warnings;
use Test::More;
use Scalar::Util 'weaken';
use Future;
# OFFLINE regression test for the "async bind-value leak" concern.
# Ported from dbio-postgresql-async t/05-bind-release.t.
#
# WHAT THIS TEST PROVES: bind values issued through the async query
# path are retained only by the issuing scope's lexical, not by any
# storage/pool cache. Once that scope ends, the bind arrayref is freed.
# This is a pure Perl reference-graph question -- no DB needed.
#
t/04-bind-release.t view on Meta::CPAN
# --- 1. single pooled query: bind released once the future completes ---
{
my $storage = new_storage;
my $pool = $storage->pool;
my $weak;
my $f;
{
my $bind = [ 'payload' x 64 ];
weaken($weak = $bind);
$f = $storage->_query_async('SELECT $1', $bind);
}
# The issuing-scope strong lexical dies here.
# Complete the query on the FakeConn4.
my $conn = $pool->{_connections}[0];
$conn->complete_one;
$f->get;
ok !defined $weak,
t/04-bind-release.t view on Meta::CPAN
my $storage = new_storage;
my $pool = $storage->pool;
# Acquire a connection manually to simulate a pinned transaction conn.
my $conn = $pool->acquire->get;
my $weak;
my $f;
{
my $bind = [ 'txn-payload' x 64 ];
weaken($weak = $bind);
$f = $storage->_query_async_pinned($conn, 'SELECT $1', $bind);
}
$conn->complete_one;
$f->get;
ok !defined $weak,
'pinned (txn) query: bind arrayref is freed after completion too';
}
t/04-bind-release.t view on Meta::CPAN
# Pre-spawn enough connections for N concurrent queries.
# Pool size is 5 by default; use 3 queries to stay within.
my $N = 3;
my @weak;
my @f;
for my $i (1 .. $N) {
my $w;
{
my $bind = [ "row$i" x 32 ];
weaken($w = $bind);
push @f, $storage->_query_async("SELECT \$1 -- $i", $bind);
}
push @weak, $w;
}
my $held_inflight = grep { defined } @weak;
is $held_inflight, 0,
"no bind arrayref is retained while $N queries are in-flight "
. '(no per-pool/per-future bind cache)';
( run in 1.102 second using v1.01-cache-2.11-cpan-995e09ba956 )