The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

AnyEvent::Pg::Pool

SYNOPSIS

  my $pool = AnyEvent::Pg::Pool->new($conninfo,
                                     on_connect_error => \&on_db_is_dead);

  my $qw = $pool->push_query(query => 'select * from foo',
                             on_result => sub { ... });

  my $lw = $pool->listen('bar',
                         on_notify => sub { ... });

DESCRIPTION

  *******************************************************************
  ***                                                             ***
  *** NOTE: This is a very early release that may contain lots of ***
  *** bugs. The API is not stable and may change between releases ***
  ***                                                             ***
  *******************************************************************

This module handles a pool of databases connections, and transparently handles reconnection and reposting queries when network and server errors occur.

API

The following methods are provided:

$pool = AnyEvent::Pg::Pool->new($conninfo, %opts)

Creates a new object.

Accepts the following options:

size => $size

Maximum number of database connections that can be simultaneously established with the server.

connection_retries => $n

Maximum number of attempts to establish a new database connection before calling the on_connect_error callback when there is no other connection alive on the pool.

connection_delay => $seconds

When establishing a new connection fails, this setting allows to configure the number of seconds to delay before trying to connect again.

timeout => $seconds

When some active connection does not report activity for the given number of seconds, it is considered dead and closed.

global_timeout => $seconds

When all the connections to the database become broken and it is not possible to establish a new connection for the given time period the pool is considered dead and the on_error callback will be called.

Note that this timeout is approximate. It is checked every time a new connection attempt fails but its expiration will not cause the abortion of an in-progress connection.

on_error => $callback

When some error happens that can not be automatically handled by the module (for instance, by requeuing the current query), this callback is invoked.

on_connect_error => $callback

When the number of failed reconnection attempts goes over the limit, this callback is called. The pool object and the AnyEvent::Pg object representing the last failed attempt are passed as arguments.

on_transient_error => $callback

The given callback is invoked every time an internal recoverable error happens (for instance, on of the pool connections fails or times out).

There is no guarantee about when this callback will be called and how many times. It should be considered just a hint.

$w = $pool->push_query(%opts)

Pushes a database query on the pool queue. It will be sent to the database once any of the database connections becomes idle.

A watcher object is returned. If that watcher goes out of scope, the query is canceled.

This method accepts all the options supported by the method of the same name on AnyEvent::Pg plus the following ones:

retry_on_sqlstate => \@states
retry_on_sqlstate => \%states

A hash of sqlstate values that are retryable. When some error happens, and the value of sqlstate from the result object has a value on this hash, the query is reset and reintroduced on the query.

max_retries => $n

Maximum number of times a query can be retried. When this limit is reached, the on_error callback will be called.

Note that queries are not retried after partial success. For instance, when a result object is returned, but then the server decides to abort the transaction (this is rare, but can happen from time to time).

priority => $n

This option allows to prioritize queries. The pool dispatches first those with the highest priority value.

The default priority is -inf.

Queries of equal priority are dispatched in FIFO order.

initialization => $bool

When this option is set, the query will be invoked for every database connection (both currently existing or created on the future) before any other query.

It can be used to set up session parameters. For instance:

  $pool->push_query(initialization => 1,
                    query => "set session time zone 'UTC'");

Pushing initialization queries does not return a watcher object. Also, once pushed, the current API does not allow removing them.

The callbacks for the push_query method receive as arguments the pool object, the underlying AnyEvent::Pg object actually handling the query and the result object when applicable. For instance:

    sub on_result_cb {
        my ($pool, $conn, $result) = @_;
        ...
    }

    sub on_done_cb {
        my ($pool, $conn) = @_;
    }

    my $watcher = $pool->push_query("select * from foo",
                                    on_result => \&on_result_cb,
                                    on_done   => \&on_done_cb);
$w = $pool->listen($channel, %opts)

This method allows to subscribe to the given notification channel and receive an event every time another sends a notification (see PostgreSQL NOTIFY/LISTEN documentation).

The module will take care of keeping an active AnyEvent::Pg connection subscribed to the channel, recovering from errors automatically.

Currently, due to some limitations on the way the LISTEN SQL command is parsed, the channel selector has to match /^[a-z]\w*$/i.

The options accepted by the method are as follow:

on_notify => $callback

The given callback will be called every time some client sends a notification for the selected channel.

The arguments to the callback are the pool object, the channel selector and any possible data load passed by the client sending the notification.

on_listener_started => $callback

When the connection is started the first time, or when recovering from some connection error, there may be a lapse of time where no connection is subscribed to the channel and notifications sent by other clients lost.

This callback is called every time a connection is subscribed to the channel. It is really a hint that allows to check in some application specific way (i.e. performing a select) that no event has been lost.

The arguments passed to the callback are the pool object and the channel selector.

$bool = $pool->is_dead

Returns a true value if the pool object has been marked as dead.

$pool->set($param1 => $value1, $param2 => $value2, ...);

Changes the values of pool parameters.

See the constructor documentation for the list of parameters that can be changed.

SEE ALSO

AnyEvent::Pg, Pg::PQ, AnyEvent.

BUGS AND SUPPORT

This is a very early release that may contain lots of bugs.

Send bug reports by email or using the CPAN bug tracker at https://rt.cpan.org/Dist/Display.html?Status=Active&Queue=AnyEvent-Pg.

Commercial support

This module was implemented during the development of QVD (http://theqvd.com) the Linux VDI platform.

Commercial support, professional services and custom software development services around this module are available from QindelGroup (http://qindel.com). Send us an email with a rough description of your requirements and we will get back to you ASAP.

AUTHOR

Salvador Fandiño, <sfandino@yahoo.com>

COPYRIGHT AND LICENSE

Copyright (C) 2012, 2013 by Qindel Formación y Servicios S.L.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.10.1 or, at your option, any later version of Perl 5 you may have available.