Commit | Line | Data |
26ab719a |
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 create_replicants (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 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 | |
131 | Returns true if there are connected replicants. Actually is overloaded to |
132 | return 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 | |
140 | This method will actually test that each replicant in the L</replicants> hashref |
141 | is actually connected, try not to hit this 10 times a second. |
142 | |
143 | =cut |
144 | |
145 | sub 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 | |
154 | Just a simple array of all the replicant storages. No particular order to the |
155 | array is given, nor should any meaning be derived. |
156 | |
157 | =cut |
158 | |
159 | sub all_replicants { |
160 | my $self = shift @_; |
161 | return values %{$self->replicants}; |
162 | } |
163 | |
164 | |
165 | =head1 AUTHOR |
166 | |
167 | John Napiorkowski <john.napiorkowski@takkle.com> |
168 | |
169 | =head1 LICENSE |
170 | |
171 | You may distribute this code under the same terms as Perl itself. |
172 | |
173 | =cut |
174 | |
175 | |
176 | 1; |