got first pass on the replication and balancer, passing all of the old test suite...
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / Replicated / Pool.pm
CommitLineData
26ab719a 1package DBIx::Class::Storage::DBI::Replicated::Pool;
2
3use Moose;
4use MooseX::AttributeHelpers;
5use DBIx::Class::Storage::DBI::Replicated::Replicant;
6use List::Util qw(sum);
7
8=head1 NAME
9
10DBIx::Class::Storage::DBI::Replicated::Pool; Manage a pool of replicants
11
12=head1 SYNOPSIS
13
14This class is used internally by L<DBIx::Class::Storage::DBI::Replicated>. You
15shouldn't need to create instances of this class.
16
17=head1 DESCRIPTION
18
19In a replicated storage type, there is at least one replicant to handle the
20read only traffic. The Pool class manages this replicant, or list of
21replicants, and gives some methods for querying information about their status.
22
23=head1 ATTRIBUTES
24
25This class defines the following attributes.
26
27=head2 replicant_type
28
29Base class used to instantiate replicants that are in the pool. Unless you
30need to subclass L<DBIx::Class::Storage::DBI::Replicated::Replicant> you should
31just leave this alone.
32
33=cut
34
35has '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
48A hashref of replicant, with the key being the dsn and the value returning the
49actual replicant storage. For example if the $dsn element is something like:
50
51 "dbi:SQLite:dbname=dbfile"
52
53You could access the specific replicant via:
54
55 $schema->storage->replicants->{'dbname=dbfile'}
56
57This attributes also supports the following helper methods
58
59=over 4
60
61=item set_replicant($key=>$storage)
62
63Pushes a replicant onto the HashRef under $key
64
65=item get_replicant($key)
66
67Retrieves the named replicant
68
69=item has_replicants
70
71Returns true if the Pool defines replicants.
72
73=item num_replicants
74
75The number of replicants in the pool
76
77=item delete_replicant ($key)
78
79removes the replicant under $key from the pool
80
81=back
82
83=cut
84
85has '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
102This class defines the following methods.
103
104=head2 create_replicants (Array[$connect_info])
105
106Given an array of $dsn suitable for connected to a database, create an
107L<DBIx::Class::Storage::DBI::Replicated::Replicant> object and store it in the
108L</replicants> attribute.
109
110=cut
111
112sub create_replicants {
113 my $self = shift @_;
114
115 my @newly_created = ();
116 foreach my $connect_info (@_) {
117 my $replicant = $self->create_replicant;
118 $replicant->connect_info($connect_info);
119 $replicant->ensure_connected;
120 my ($key) = ($connect_info->[0]=~m/^dbi\:.+\:(.+)$/);
121 $self->set_replicant( $key => $replicant);
122 push @newly_created, $replicant;
123 }
124
125 return @newly_created;
126}
127
128
129=head2 connected_replicants
130
131Returns true if there are connected replicants. Actually is overloaded to
132return the number of replicants. So you can do stuff like:
133
134 if( my $num_connected = $storage->has_connected_replicants ) {
135 print "I have $num_connected connected replicants";
136 } else {
137 print "Sorry, no replicants.";
138 }
139
140This method will actually test that each replicant in the L</replicants> hashref
141is actually connected, try not to hit this 10 times a second.
142
143=cut
144
145sub connected_replicants {
146 my $self = shift @_;
147 return sum( map {
148 $_->connected ? 1:0
149 } $self->all_replicants );
150}
151
152=head2 all_replicants
153
154Just a simple array of all the replicant storages. No particular order to the
155array is given, nor should any meaning be derived.
156
157=cut
158
159sub all_replicants {
160 my $self = shift @_;
161 return values %{$self->replicants};
162}
163
164
165=head1 AUTHOR
166
167John Napiorkowski <john.napiorkowski@takkle.com>
168
169=head1 LICENSE
170
171You may distribute this code under the same terms as Perl itself.
172
173=cut
174
175
1761;