X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FStorage%2FDBI%2FReplicated%2FBalancer.pm;h=ed7007d3d52f8db9d91a9b928734490199022d76;hb=17b05c131035f73964c434c1a9c8b28e46aebeeb;hp=7ca7cffec984e900f5b9ff2546dd54875b30732c;hpb=106d5f3b7e03a68fb2e125772e3f06a34115f22d;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Storage/DBI/Replicated/Balancer.pm b/lib/DBIx/Class/Storage/DBI/Replicated/Balancer.pm index 7ca7cff..ed7007d 100644 --- a/lib/DBIx/Class/Storage/DBI/Replicated/Balancer.pm +++ b/lib/DBIx/Class/Storage/DBI/Replicated/Balancer.pm @@ -1,6 +1,7 @@ package DBIx::Class::Storage::DBI::Replicated::Balancer; -use Moose; +use Moose::Role; +requires 'next_storage'; =head1 NAME @@ -8,8 +9,7 @@ DBIx::Class::Storage::DBI::Replicated::Balancer; A Software Load Balancer =head1 SYNOPSIS -This class is used internally by L. You -shouldn't need to create instances of this class. +This role is used internally by L. =head1 DESCRIPTION @@ -21,6 +21,20 @@ method by which query load can be spread out across each replicant in the pool. This class defines the following attributes. +=head2 auto_validate_every ($seconds) + +If auto_validate has some sort of value, run the L every +$seconds. Be careful with this, because if you set it to 0 you will end up +validating every query. + +=cut + +has 'auto_validate_every' => ( + is=>'rw', + isa=>'Int', + predicate=>'has_auto_validate_every', +); + =head2 master The L object that is the master database all the @@ -89,6 +103,8 @@ sub _build_current_replicant { =head2 next_storage +This method should be defined in the class which consumes this role. + Given a pool object, return the next replicant that will serve queries. The default behavior is to grap the first replicant it finds but you can write your own subclasses of L to @@ -97,13 +113,32 @@ support other balance systems. This returns from the pool of active replicants. If there are no active replicants, then you should have it return the master as an ultimate fallback. +=head2 around: next_storage + +Advice on next storage to add the autovalidation. We have this broken out so +that it's easier to break out the auto validation into a role. + +This also returns the master in the case that none of the replicants are active +or just just forgot to create them :) + =cut -sub next_storage { - my $self = shift @_; - my $next = ($self->pool->active_replicants)[0]; - return $next ? $next:$self->master; -} +around 'next_storage' => sub { + my ($next_storage, $self, @args) = @_; + my $now = time; + + ## Do we need to validate the replicants? + if( + $self->has_auto_validate_every && + ($self->auto_validate_every + $self->pool->last_validated) <= $now + ) { + $self->pool->validate_replicants; + } + + ## Get a replicant, or the master if none + my $next = $self->$next_storage(@args); + return $next ? $next:$self->master; +}; =head2 before: select