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