::DBI::Replicated - add master_read_weight to ::Random balancer_type
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / Replicated / Balancer / Random.pm
1 package DBIx::Class::Storage::DBI::Replicated::Balancer::Random;
2
3 use Moose;
4 with 'DBIx::Class::Storage::DBI::Replicated::Balancer';
5 use DBIx::Class::Storage::DBI::Replicated::Types 'Weight';
6 use namespace::clean -except => 'meta';
7
8 =head1 NAME
9
10 DBIx::Class::Storage::DBI::Replicated::Balancer::Random - A 'random' Balancer
11
12 =head1 SYNOPSIS
13
14 This class is used internally by L<DBIx::Class::Storage::DBI::Replicated>.  You
15 shouldn't need to create instances of this class.
16     
17 =head1 DESCRIPTION
18
19 Given a pool (L<DBIx::Class::Storage::DBI::Replicated::Pool>) of replicated
20 database's (L<DBIx::Class::Storage::DBI::Replicated::Replicant>), defines a
21 method by which query load can be spread out across each replicant in the pool.
22
23 This Balancer uses L<List::Util> keyword 'shuffle' to randomly pick an active
24 replicant from the associated pool.  This may or may not be random enough for
25 you, patches welcome.
26
27 =head1 ATTRIBUTES
28
29 This class defines the following attributes.
30
31 =head2 master_read_weight
32
33 A number from 0 to 1 that specifies what weight to give the master when choosing
34 which backend to execute a read query on. A value of 0, which is the default,
35 does no reads from master, while a value of 1 gives it the same priority as any
36 single replicant.
37
38 =cut
39
40 has master_read_weight => (is => 'rw', isa => Weight, default => sub { 0 });
41
42 =head1 METHODS
43
44 This class defines the following methods.
45
46 =head2 next_storage
47
48 Returns an active replicant at random.  Please note that due to the nature of
49 the word 'random' this means it's possible for a particular active replicant to
50 be requested several times in a row.
51
52 =cut
53
54 sub next_storage {
55   my $self = shift @_;
56
57   my @replicants = $self->pool->active_replicants;
58   my $master     = $self->master;
59
60   my $rnd = $self->random_number(@replicants + $self->master_read_weight);
61
62   return $rnd >= @replicants ? $master : $replicants[int $rnd];
63 }
64
65 =head2 random_number
66
67 Returns a random number from 0 to x, not including x. Uses perl's
68 L<perlfunc/rand> by default.
69
70 =cut
71
72 sub random_number {
73   rand($_[1])
74 }
75
76 =head1 AUTHOR
77
78 John Napiorkowski <john.napiorkowski@takkle.com>
79
80 =head1 LICENSE
81
82 You may distribute this code under the same terms as Perl itself.
83
84 =cut
85
86 __PACKAGE__->meta->make_immutable;
87
88 1;