Aniki

 view release on metacpan or  search on metacpan

lib/Aniki/Handler/WeightedRoundRobin.pm  view on Meta::CPAN

package Aniki::Handler::WeightedRoundRobin;
use 5.014002;

use namespace::autoclean;
use Mouse;
extends qw/Aniki::Handler/;

use DBI ();
use Data::WeightedRoundRobin;
use Scalar::Util qw/refaddr/;

around BUILDARGS => sub {
    my $orig = shift;
    my $self = shift;
    my %args = (@_ == 1 && ref $_[0] eq 'HASH') ? %{$_[0]} : @_;

    my $connect_info = delete $args{connect_info};
    my $rr = Data::WeightedRoundRobin->new([
        map {
            +{
                %$_,
                key => refaddr($_->{value}),
            }
        } @$connect_info
    ]);
    return $self->$orig(rr => $rr);
};

has rr => (
    is       => 'ro',
    required => 1,
);

has '+connect_info' => (
    is       => 'rw',
    required => 0,
    lazy     => 1,
    builder  => sub { shift->rr->next },
    clearer  => '_reset_connect_info',
);

sub is_connect_error {
    my ($self, $e) = @_;
    my ($dsn) = @{ $self->connect_info };
    my (undef, $driver) = DBI->parse_dsn($dsn);

    if ($driver eq 'mysql') {
        return $e =~ /\Qfailed: Can't connect to MySQL server on/m;
    }
    elsif ($driver eq 'Pg') {
        return $e =~ /\Qfailed: could not connect to server: Connection refused/m;
    }
    elsif ($driver eq 'Oracle') {
        # TODO: patches wellcome :p
    }

    warn "Unsupported dirver: $driver";
    return 0;
}

sub disconnect {
    my $self = shift;
    $self->_reset_connect_info();
    $self->SUPER::disconnect();



( run in 0.363 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )