reverse r4290 since we -do- -not- currently want these namespaces indexed
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Schema / Role / AtQueryInterval.pm
CommitLineData
25e4a0c4 1package DBIx::Class::Schema::Role::AtQueryInterval;
2
3use Moose::Role;
4use MooseX::AttributeHelpers;
5use DBIx::Class::Schema::Job;
6use DBIx::Class::Schema::QueryInterval;
7use DBIx::Class::Schema::AtQueryInterval;
8
9=head1 NAME
10
11DBIx::Class::Schema::Role::AtQueryInterval; Execute code at query intervals
12
13=head1 SYNOPSIS
14
15The follow will execute the 'do_something' method each and every 10 queries,
16excute a subref each 20 queries, and do both each 30 queries. This first
17example is the long, hard way.
18
19 ## ISA DBIx::Class::Schema::Job
20
21 my $job1 = $schema->create_job(
22 runs => 'do_something',
23 );
24
25 my $job2 = $schema->create_job(
26 runs => sub {warn 'queries counted'},
27 );
28
29
30 ## ISA DBIx::Class::Schema::QueryInterval
31
32 my $interval_10 = $schema->create_query_interval(every => 10);
33 my $interval_20 = $schema->create_query_interval(every => 20);
34 my $interval_30 = $schema->create_query_interval(every => 30);
35
36
37 ## USA DBIx::Class::Schema::AtQueryInterval
38
39 my $at1 = $schema->create_at_query_interval(
40 interval => $interval_10, job => $job1,
41 );
42
43 my $at2 = $schema->create_at_query_interval(
44 interval => $interval_20, job => $job2,
45 );
46
47 my $at3 = $schema->create_at_query_interval(
48 interval => $interval_30, job=>$job1,
49 );
50
51 my $at4 = $schema->create_at_query_interval(
52 interval => $interval_30, job=>$job2,
53 );
54
55 $schema->query_intervals([$1, $at2, $at3, $at4]);
56
57Or you can take the express trip (assuming you are not creating any custom
58Query Intervals, Jobs, etc.) Notice that this method allows jobs to be defined
59as an arrayref to make it easier to defined multiple jobs for a given interval.
60
61In order to perform the needed object instantiation, this class will use the
62methods 'query_interval_class', 'job_class' and 'at_query_interval_class'.
63
64 $schema->create_and_add_at_query_intervals(
65 {every => 10} => {
66 runs => 'do_something',
67 },
68 {every => 20} => {
69 runs => sub {
70 warn 'queries counted';
71 },
72 },
73 {every => 30} => [
74 {runs => 'do_something'},
75 {runs => sub{
76 warn 'queries counted';
77 }},
78 ],
79 );
80
81All the above sit in a DBIx::Class::Schema that consumes the proper roles and
82defines a function which receives three arguments:
83
84 sub do_something {
85 my ($job, $schema, $at_query_interval) = @_;
86 }
87
88=head1 DESCRIPTION
89
90Sometime you'd like to perform certain housekeeping activities at preset query
91intervals. For example, every 100 queries you want to update a reporting table
92that contains denormalized information. This role allows you to assign a
93scalar containing the name of a method in your schema class, an anonymous sub,
94or an arrayref of either to a particular interval.
95
96=head1 ATTRIBUTES
97
98This package defines the following attributes.
99
100=head2 query_interval_class
101
102The default class used to create an interval class from a hash of initializing
103information.
104
105=cut
106
107has 'query_interval_class' => (
108 is=>'ro',
109 isa=>'ClassName',
110 required=>1,
111 default=>'DBIx::Class::Schema::QueryInterval',
112 handles=> {
113 'create_query_interval' => 'new',
114 },
115);
116
117
118=head2 job_class
119
120The default class used to create an job class from a hash of initializing
121information.
122
123=cut
124
125has 'job_class' => (
126 is=>'ro',
127 isa=>'ClassName',
128 required=>1,
129 default=>'DBIx::Class::Schema::Job',
130 handles=> {
131 'create_job' => 'new',
132 },
133);
134
135
136=head2 at_query_interval_class
137
138The default class used to create an job class from a hash of initializing
139information.
140
141=cut
142
143has 'at_query_interval_class' => (
144 is=>'ro',
145 isa=>'ClassName',
146 required=>1,
147 default=>'DBIx::Class::Schema::AtQueryInterval',
148 handles=> {
149 'create_at_query_interval' => 'new',
150 },
151);
152
153
154=head2 at_query_intervals
155
156This is an arrayref of L<DBIx::Class::Schema::AtQueryInterval> objects which
157holds all the jobs that need to be run at the given interval.
158
159=cut
160
161has 'at_query_intervals' => (
162 is=>'rw',
163 metaclass => 'Collection::Array',
164 auto_deref => 1,
165 isa=>'ArrayRef[DBIx::Class::Schema::AtQueryInterval]',
166 provides => {
167 push => 'add_at_query_interval',
168 },
169);
170
171
172=head1 METHODS
173
174This module defines the following methods.
175
176=head2 execute_jobs_at_query_interval ($int)
177
178Execute all the jobs which match the given interval
179
180=cut
181
182sub execute_jobs_at_query_interval {
183 my ($self, $query_count, @args) = @_;
184 my @responses;
185 foreach my $at ($self->at_query_intervals) {
186 push @responses,
187 $at->execute_if_matches($query_count, $self, @args);
188 }
189 return @responses;
190}
191
192
193=head2 create_and_add_at_query_intervals (%definitions)
194
195Uses the shortcut method shown above to quickly build a plan from a simple perl
196array of hashes.
197
198=cut
199
200sub create_and_add_at_query_intervals {
201 my ($self, @definitions) = @_;
202 while (@definitions) {
203 my $interval = $self->normalize_query_interval(shift @definitions);
204 my @jobs = $self->normalize_to_jobs(shift @definitions);
205 foreach my $job (@jobs) {
206 my $at = $self->create_at_query_interval(interval=>$interval, job=>$job);
207 $self->add_at_query_interval($at);
208 }
209 }
210}
ae89f08e 211
25e4a0c4 212
213=head2 normalize_query_interval ($hash||$obj)
214
215Given an argument, make sure it's a L<DBIx::Class::Schema::QueryInterval>,
216coercing it if neccessary.
217
218=cut
219
220sub normalize_query_interval {
221 my ($self, $arg) = @_;
222 if(blessed $arg && $arg->isa('DBIx::Class::Schema::QueryInterval')) {
223 return $arg;
224 } else {
225 return $self->create_query_interval($arg);
226 }
227}
228
ae89f08e 229
25e4a0c4 230=head2 normalize_to_jobs ($hash||$obj||$arrayref)
231
232Incoming jobs need to be normalized to an array, so that we can handle adding
233multiple jobs per interval.
234
235=cut
236
237sub normalize_to_jobs {
238 my ($self, $arg) = @_;
239 my @jobs = ref $arg eq 'ARRAY' ? @$arg : ($arg);
240 return map {$self->normalize_job($_)} @jobs;
241}
242
243
244=head2 normalize_job ($hash||$obj)
245
246Given an argument, make sure it's a L<DBIx::Class::Schema::Job>,
247coercing it if neccessary.
248
249=cut
250
251sub normalize_job {
252 my ($self, $arg) = @_;
253 if(blessed $arg && $arg->isa('DBIx::Class::Schema::Job')) {
254 return $arg;
255 } else {
256 return $self->create_job($arg);
257 }
258}
259
260
261=head1 AUTHORS
262
263See L<DBIx::Class> for more information regarding authors.
264
265=head1 LICENSE
266
267You may distribute this code under the same terms as Perl itself.
268
269=cut
270
271
2721;