Commit | Line | Data |
26ab719a |
1 | package DBIx::Class::Storage::DBI::Replicated::Balancer; |
2 | |
3 | use Moose; |
26ab719a |
4 | |
5 | =head1 NAME |
6 | |
7 | DBIx::Class::Storage::DBI::Replicated::Balancer; A Software Load Balancer |
8 | |
9 | =head1 SYNOPSIS |
10 | |
11 | This class is used internally by L<DBIx::Class::Storage::DBI::Replicated>. You |
12 | shouldn't need to create instances of this class. |
13 | |
14 | =head1 DESCRIPTION |
15 | |
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. |
19 | |
20 | =head1 ATTRIBUTES |
21 | |
22 | This class defines the following attributes. |
23 | |
cb6ec758 |
24 | =head2 pool |
25 | |
26 | The L<DBIx::Class::Storage::DBI::Replicated::Pool> object that we are trying to |
27 | balance. |
28 | |
29 | =cut |
30 | |
31 | has 'pool' => ( |
32 | is=>'ro', |
33 | isa=>'DBIx::Class::Storage::DBI::Replicated::Pool', |
34 | required=>1, |
35 | ); |
36 | |
37 | =head2 current_replicant |
38 | |
39 | Replicant storages (slaves) handle all read only traffic. The assumption is |
40 | that your database will become readbound well before it becomes write bound |
41 | and that being able to spread your read only traffic around to multiple |
42 | databases is going to help you to scale traffic. |
43 | |
44 | This attribute returns the next slave to handle a read request. Your L</pool> |
45 | attribute has methods to help you shuffle through all the available replicants |
46 | via it's balancer object. |
47 | |
48 | =cut |
49 | |
50 | has 'current_replicant' => ( |
51 | is=> 'rw', |
52 | isa=>'DBIx::Class::Storage::DBI', |
53 | lazy_build=>1, |
54 | handles=>[qw/ |
55 | select |
56 | select_single |
57 | columns_info_for |
58 | /], |
59 | ); |
60 | |
26ab719a |
61 | =head1 METHODS |
62 | |
63 | This class defines the following methods. |
64 | |
cb6ec758 |
65 | =head2 _build_current_replicant |
66 | |
67 | Lazy builder for the L</current_replicant_storage> attribute. |
68 | |
69 | =cut |
70 | |
71 | sub _build_current_replicant { |
72 | my $self = shift @_; |
73 | $self->next_storage($self->pool); |
74 | } |
75 | |
76 | =head2 next_storage |
26ab719a |
77 | |
78 | Given a pool object, return the next replicant that will serve queries. The |
cb6ec758 |
79 | default behavior is to grap the first replicant it finds but you can write |
80 | your own subclasses of L<DBIx::Class::Storage::DBI::Replicated::Balancer> to |
81 | support other balance systems. |
26ab719a |
82 | |
83 | =cut |
84 | |
85 | sub next_storage { |
86 | my $self = shift @_; |
cb6ec758 |
87 | return ($self->pool->active_replicants)[0] |
88 | if $self->pool->active_replicants; |
26ab719a |
89 | } |
90 | |
cb6ec758 |
91 | =head2 after: select |
92 | |
93 | Advice on the select attribute. Each time we use a replicant |
94 | we need to change it via the storage pool algorithm. That way we are spreading |
95 | the load evenly (hopefully) across existing capacity. |
96 | |
97 | =cut |
98 | |
99 | after 'select' => sub { |
100 | my $self = shift @_; |
101 | my $next_replicant = $self->next_storage; |
102 | $self->current_replicant($next_replicant); |
103 | }; |
104 | |
105 | =head2 after: select_single |
106 | |
107 | Advice on the select_single attribute. Each time we use a replicant |
108 | we need to change it via the storage pool algorithm. That way we are spreading |
109 | the load evenly (hopefully) across existing capacity. |
110 | |
111 | =cut |
112 | |
113 | after 'select_single' => sub { |
114 | my $self = shift @_; |
115 | my $next_replicant = $self->next_storage; |
116 | $self->current_replicant($next_replicant); |
117 | }; |
118 | |
119 | =head2 after: columns_info_for |
120 | |
121 | Advice on the current_replicant_storage attribute. Each time we use a replicant |
122 | we need to change it via the storage pool algorithm. That way we are spreading |
123 | the load evenly (hopefully) across existing capacity. |
124 | |
125 | =cut |
126 | |
127 | after 'columns_info_for' => sub { |
128 | my $self = shift @_; |
129 | my $next_replicant = $self->next_storage; |
130 | $self->current_replicant($next_replicant); |
131 | }; |
26ab719a |
132 | |
133 | =head1 AUTHOR |
134 | |
135 | John Napiorkowski <john.napiorkowski@takkle.com> |
136 | |
137 | =head1 LICENSE |
138 | |
139 | You may distribute this code under the same terms as Perl itself. |
140 | |
141 | =cut |
142 | |
cb6ec758 |
143 | 1; |