1 package DBIx::Class::Storage::DBI::Replicated::Balancer;
7 DBIx::Class::Storage::DBI::Replicated::Balancer; A Software Load Balancer
11 This class is used internally by L<DBIx::Class::Storage::DBI::Replicated>. You
12 shouldn't need to create instances of this class.
16 Given a pool (L<DBIx::Class::Storage::DBI::Replicated::Pool>) of replicated
17 database's (L<DBIx::Class::Storage::DBI::Replicated::Replicant>), defines a
18 method by which query load can be spread out across each replicant in the pool.
22 This class defines the following attributes.
24 =head2 auto_validate_every ($seconds)
26 If auto_validate has some sort of value, run the L<validate_replicants> every
27 $seconds. Be careful with this, because if you set it to 0 you will end up
28 validating every query.
32 has 'auto_validate_every' => (
35 predicate=>'had_auto_validate_every',
40 This is an integer representing a time since the last time the replicants were
41 validated. It's nothing fancy, just an integer provided via the perl time
46 has 'last_validated' => (
49 reader=>'last_validated',
50 writer=>'_last_validated',
59 The L<DBIx::Class::Storage::DBI> object that is the master database all the
60 replicants are trying to follow. The balancer needs to know it since it's the
67 isa=>'DBIx::Class::Storage::DBI',
73 The L<DBIx::Class::Storage::DBI::Replicated::Pool> object that we are trying to
80 isa=>'DBIx::Class::Storage::DBI::Replicated::Pool',
84 =head2 current_replicant
86 Replicant storages (slaves) handle all read only traffic. The assumption is
87 that your database will become readbound well before it becomes write bound
88 and that being able to spread your read only traffic around to multiple
89 databases is going to help you to scale traffic.
91 This attribute returns the next slave to handle a read request. Your L</pool>
92 attribute has methods to help you shuffle through all the available replicants
93 via it's balancer object.
97 has 'current_replicant' => (
99 isa=>'DBIx::Class::Storage::DBI',
110 This class defines the following methods.
112 =head2 _build_current_replicant
114 Lazy builder for the L</current_replicant_storage> attribute.
118 sub _build_current_replicant {
125 Given a pool object, return the next replicant that will serve queries. The
126 default behavior is to grap the first replicant it finds but you can write
127 your own subclasses of L<DBIx::Class::Storage::DBI::Replicated::Balancer> to
128 support other balance systems.
130 This returns from the pool of active replicants. If there are no active
131 replicants, then you should have it return the master as an ultimate fallback.
133 TODO this needs to wrap for the subclasses better. Maybe good use of INNER?
140 ## Do we need to validate the replicants?
142 $self->had_auto_validate_every &&
143 ($self->auto_validate_every + $self->last_validated) > time
145 $self->pool->validate_replicants;
146 $self->_last_validated(time);
149 ## Get a replicant, or the master if none
150 my $next = ($self->pool->active_replicants)[0];
151 return $next ? $next:$self->master;
154 =head2 before: select
156 Advice on the select attribute. Each time we use a replicant
157 we need to change it via the storage pool algorithm. That way we are spreading
158 the load evenly (hopefully) across existing capacity.
162 before 'select' => sub {
164 my $next_replicant = $self->next_storage;
165 $self->current_replicant($next_replicant);
168 =head2 before: select_single
170 Advice on the select_single attribute. Each time we use a replicant
171 we need to change it via the storage pool algorithm. That way we are spreading
172 the load evenly (hopefully) across existing capacity.
176 before 'select_single' => sub {
178 my $next_replicant = $self->next_storage;
179 $self->current_replicant($next_replicant);
182 =head2 before: columns_info_for
184 Advice on the current_replicant_storage attribute. Each time we use a replicant
185 we need to change it via the storage pool algorithm. That way we are spreading
186 the load evenly (hopefully) across existing capacity.
190 before 'columns_info_for' => sub {
192 my $next_replicant = $self->next_storage;
193 $self->current_replicant($next_replicant);
198 John Napiorkowski <john.napiorkowski@takkle.com>
202 You may distribute this code under the same terms as Perl itself.