X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FStorage%2FDBI%2FReplicated%2FPool.pm;h=76ca7f224d1cf2e63296e0d5aee9c91ff723be5e;hb=6ffb5be522e752ea1ad2a99d36648535fe30a43b;hp=b1cdc821713f6e34043597235cfd241f5ba5cb1e;hpb=21fc471939bf782a3ae38f8c71a4563fe50592d3;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Storage/DBI/Replicated/Pool.pm b/lib/DBIx/Class/Storage/DBI/Replicated/Pool.pm index b1cdc82..76ca7f2 100644 --- a/lib/DBIx/Class/Storage/DBI/Replicated/Pool.pm +++ b/lib/DBIx/Class/Storage/DBI/Replicated/Pool.pm @@ -168,14 +168,40 @@ and return it. sub connect_replicant { my ($self, $schema, $connect_info) = @_; my $replicant = $self->create_replicant($schema); - - $replicant->connect_info($connect_info); - $replicant->ensure_connected; - DBIx::Class::Storage::DBI::Replicated::Replicant->meta->apply($replicant); - + $replicant->connect_info($connect_info); + $self->_safely_ensure_connected($replicant); + DBIx::Class::Storage::DBI::Replicated::Replicant->meta->apply($replicant); return $replicant; } +=head2 _safely_ensure_connected ($replicant) + +The standard ensure_connected method with throw an exception should it fail to +connect. For the master database this is desirable, but since replicants are +allowed to fail, this behavior is not desirable. This method wraps the call +to ensure_connected in an eval in order to catch any generated errors. That +way a slave to go completely offline (ie, the box itself can die) without +bringing down your entire pool of databases. + +=cut + +sub _safely_ensure_connected { + my ($self, $replicant, @args) = @_; + eval { + $replicant->ensure_connected(@args); + }; + if ($@) { + $replicant + ->debugobj + ->print( + sprintf( "Exception trying to ->ensure_connected for replicant %s, error is %s", + $replicant->_dbi_connect_info->[0], $@) + ); + return; + } + return 1; +} + =head2 connected_replicants Returns true if there are connected replicants. Actually is overloaded to @@ -242,23 +268,43 @@ connection is not following a master or is lagging. Calling this method will generate queries on the replicant databases so it is not recommended that you run them very often. +This method requires that your underlying storage engine supports some sort of +native replication mechanism. Currently only MySQL native replication is +supported. Your patches to make other replication types work are welcomed. + =cut sub validate_replicants { my $self = shift @_; foreach my $replicant($self->all_replicants) { - if( - $replicant->is_replicating && - $replicant->lag_behind_master <= $self->maximum_lag && - $replicant->ensure_connected - ) { - $replicant->active(1) + if($self->_safely_ensure_connected($replicant)) { + my $is_replicating = $replicant->is_replicating; + unless(defined $is_replicating) { + $replicant->debugobj->print("Storage Driver ".ref $self." Does not support the 'is_replicating' method. Assuming you are manually managing."); + next; + } else { + if($is_replicating) { + my $lag_behind_master = $replicant->lag_behind_master; + unless(defined $lag_behind_master) { + $replicant->debugobj->print("Storage Driver ".ref $self." Does not support the 'lag_behind_master' method. Assuming you are manually managing."); + next; + } else { + if($lag_behind_master <= $self->maximum_lag) { + $replicant->active(1); + } else { + $replicant->active(0); + } + } + } else { + $replicant->active(0); + } + } } else { $replicant->active(0); } } ## Mark that we completed this validation. - $self->_last_validated(time); + $self->_last_validated(time); } =head1 AUTHOR