cleanup of some docs, got the default shuffling balancer to work properly. Don't...
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / Replicated / Pool.pm
1 package DBIx::Class::Storage::DBI::Replicated::Pool;
2
3 use Moose;
4 use MooseX::AttributeHelpers;
5 use DBIx::Class::Storage::DBI::Replicated::Replicant;
6 use List::Util qw(sum);
7
8 =head1 NAME
9
10 DBIx::Class::Storage::DBI::Replicated::Pool; Manage a pool of replicants
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 In a replicated storage type, there is at least one replicant to handle the
20 read only traffic.  The Pool class manages this replicant, or list of 
21 replicants, and gives some methods for querying information about their status.
22
23 =head1 ATTRIBUTES
24
25 This class defines the following attributes.
26
27 =head2 replicant_type
28
29 Base class used to instantiate replicants that are in the pool.  Unless you
30 need to subclass L<DBIx::Class::Storage::DBI::Replicated::Replicant> you should
31 just leave this alone.
32
33 =cut
34
35 has 'replicant_type' => (
36     is=>'ro',
37     isa=>'ClassName',
38     required=>1,
39     default=>'DBIx::Class::Storage::DBI::Replicated::Replicant',
40     handles=>{
41         'create_replicant' => 'new',
42     },  
43 );
44
45
46 =head2 replicants
47
48 A hashref of replicant, with the key being the dsn and the value returning the
49 actual replicant storage.  For example if the $dsn element is something like:
50
51     "dbi:SQLite:dbname=dbfile"
52     
53 You could access the specific replicant via:
54
55     $schema->storage->replicants->{'dbname=dbfile'}
56     
57 This attributes also supports the following helper methods
58
59 =over 4
60
61 =item set_replicant($key=>$storage)
62
63 Pushes a replicant onto the HashRef under $key
64
65 =item get_replicant($key)
66
67 Retrieves the named replicant
68
69 =item has_replicants
70
71 Returns true if the Pool defines replicants.
72
73 =item num_replicants
74
75 The number of replicants in the pool
76
77 =item delete_replicant ($key)
78
79 removes the replicant under $key from the pool
80
81 =back
82
83 =cut
84
85 has 'replicants' => (
86     is=>'rw',
87     metaclass => 'Collection::Hash',
88     isa=>'HashRef[DBIx::Class::Storage::DBI::Replicated::Replicant]',
89     default=>sub {{}},
90     provides  => {
91                 'set' => 'set_replicant',
92                 'get' => 'get_replicant',            
93                 'empty' => 'has_replicants',
94                 'count' => 'num_replicants',
95                 'delete' => 'delete_replicant',
96         },
97 );
98
99
100 =head1 METHODS
101
102 This class defines the following methods.
103
104 =head2 connect_replicants ($schema, Array[$connect_info])
105
106 Given an array of $dsn suitable for connected to a database, create an
107 L<DBIx::Class::Storage::DBI::Replicated::Replicant> object and store it in the
108 L</replicants> attribute.
109
110 =cut
111
112 sub connect_replicants {
113         my $self = shift @_;
114         my $schema = shift @_;
115         
116         my @newly_created = ();
117         foreach my $connect_info (@_) {
118                 my $replicant = $self->create_replicant($schema);
119                 $replicant->connect_info($connect_info);
120                 $replicant->ensure_connected;
121                 my ($key) = ($connect_info->[0]=~m/^dbi\:.+\:(.+)$/);
122                 $self->set_replicant( $key => $replicant);      
123                 push @newly_created, $replicant;
124         }
125         
126         return @newly_created;
127 }
128
129
130 =head2 connected_replicants
131
132 Returns true if there are connected replicants.  Actually is overloaded to
133 return the number of replicants.  So you can do stuff like:
134
135     if( my $num_connected = $storage->has_connected_replicants ) {
136         print "I have $num_connected connected replicants";
137     } else {
138         print "Sorry, no replicants.";
139     }
140
141 This method will actually test that each replicant in the L</replicants> hashref
142 is actually connected, try not to hit this 10 times a second.
143
144 =cut
145
146 sub connected_replicants {
147         my $self = shift @_;
148         return sum( map {
149                 $_->connected ? 1:0
150         } $self->all_replicants );
151 }
152
153 =head2 active_replicants
154
155 This is an array of replicants that are considered to be active in the pool.
156 This does not check to see if they are connected, but if they are not, DBIC
157 should automatically reconnect them for us when we hit them with a query.
158
159 =cut
160
161 sub active_replicants {
162     my $self = shift @_;
163     return ( grep {$_} map {
164         $_->active ? $_:0
165     } $self->all_replicants );
166 }
167
168 =head2 all_replicants
169
170 Just a simple array of all the replicant storages.  No particular order to the
171 array is given, nor should any meaning be derived.
172
173 =cut
174
175 sub all_replicants {
176         my $self = shift @_;
177         return values %{$self->replicants};
178 }
179
180
181 =head1 AUTHOR
182
183 John Napiorkowski <john.napiorkowski@takkle.com>
184
185 =head1 LICENSE
186
187 You may distribute this code under the same terms as Perl itself.
188
189 =cut
190
191
192 1;