cleaned up some debug prints
[urisagit/Stem.git] / lib / Stem / Gather.pm
CommitLineData
4536f655 1# File: Stem/Gather.pm
2
3# This file is part of Stem.
4# Copyright (C) 1999, 2000, 2001 Stem Systems, Inc.
5
6# Stem is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10
11# Stem is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15
16# You should have received a copy of the GNU General Public License
17# along with Stem; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20# For a license to use the Stem under conditions other than those
21# described here, to purchase support for this software, or to purchase a
22# commercial warranty contract, please contact Stem Systems at:
23
24# Stem Systems, Inc. 781-643-7504
25# 79 Everett St. info@stemsystems.com
26# Arlington, MA 02474
27# USA
28
29package Stem::Gather ;
30
31#use Stem::Trace 'log' => 'stem_status', 'sub' => 'TraceStatus' ;
32#use Stem::Trace 'log' => 'stem_error' , 'sub' => 'TraceError' ;
33
34=head1 Description
35
36This is a object module used by Stem Cells and objects to detect when
37a set of asynchronous events have finished. It is constructed by an
38owner object which then stores it in itselt. Gather objects are
39initialized with a set of keys to be gathered. When the owner object
40is notified of an event, it calls the C<gathered> method of the gather
41object with a list of keys. When all of the keys are gathered, a
42callback is made to the owner object. An optional timeout is available
43which will also generate a callback if the keys are not gathered in
44time.
45
46=head1 Synopsis
47
48 use Stem::Gather ;
49
50 # $self is the owner object that has already been created
51
52 my $gather = Stem::Gather->new(
53 'object' => $self,
54 'keys' => [qw( msg1 msg2 )]
55 ) ;
56
57 $self->{'gather'} = $gather ;
58
59 sub msg1_in {
60
61 my( $self ) = @_ ;
62 $self->{'gather'}->gathered( 'msg1' ) ;
63 }
64
65 sub msg2_in {
66
67 my( $self ) = @_ ;
68 $self->{'gather'}->gathered( 'msg2' ) ;
69 }
70
71 sub gather_done {
72
73 my( $self ) = @_ ;
74
75 print "we have gathered\n" ;
76 }
77
78=cut
79
80use strict ;
81
82my %class_to_attr_name ;
83
84my $attr_spec = [
85
86 {
87 'name' => 'object',
88 'required' => 1,
89 'type' => 'object',
90 'help' => <<HELP,
91This is the owner object which has the methods that get called when Stem::Gather
92has either finished gathering all of the keys or it has timed out.
93HELP
94 },
95 {
96 'name' => 'keys',
97 'required' => 1,
98 'type' => 'list',
99 'help' => <<HELP,
100This is the list of keys to gather.
101HELP
102 },
103 {
104 'name' => 'gathered_method',
105 'default' => 'gather_done',
106 'help' => <<HELP,
107This method is called in the owner object when all of the keys are gathered.
108HELP
109 },
110 {
111 'name' => 'no_start',
112 'type' => 'boolean',
113 'help' => <<HELP,
114If set, then do not start the gather object upon creation. A call to
115the C<restart> must be made. This only meaningful if this gather has a
116timeout set.
117HELP
118 },
119 {
120 'name' => 'timeout',
121 'help' => <<HELP,
122This is an optional timeout period (in seconds) waiting for the gather
123to be completed
124HELP
125 },
126 {
127 'name' => 'timeout_method',
128 'default' => 'gather_timeout',
129 'help' => <<HELP,
130This method is called in the owner object if the gather timed out
131before all keys were gathered.
132HELP
133 },
134] ;
135
136
137###########
138# This POD section is autoegenerated. Any edits to it will be lost.
139
140=head2 Constructor Attributes for Class Stem::Gather
141
142=over 4
143
144
145=item * Attribute - B<object>
146
147=over 4
148
149
150=item Description:
151This is the owner object which has the methods that get called when Stem::Gather
152has either finished gathering all of the keys or it has timed out.
153
154
155=item Its B<type> is: object
156
157=item It is B<required>.
158
159=back
160
161=item * Attribute - B<keys>
162
163=over 4
164
165
166=item Description:
167This is the list of keys to gather.
168
169
170=item Its B<type> is: list
171
172=item It is B<required>.
173
174=back
175
176=item * Attribute - B<gathered_method>
177
178=over 4
179
180
181=item Description:
182This method is called in the owner object when all of the keys are gathered.
183
184
185=item It B<defaults> to: gather_done
186
187=back
188
189=item * Attribute - B<no_start>
190
191=over 4
192
193
194=item Description:
195If set, then do not start the gather object upon creation. A call to
196the C<restart> must be made. This only meaningful if this gather has a
197timeout set.
198
199
200=item Its B<type> is: boolean
201
202=back
203
204=item * Attribute - B<timeout>
205
206=over 4
207
208
209=item Description:
210This is an optional timeout period (in seconds) waiting for the gather
211to be completed
212
213
214=back
215
216=item * Attribute - B<timeout_method>
217
218=over 4
219
220
221=item Description:
222This method is called in the owner object if the gather timed out
223before all keys were gathered.
224
225
226=item It B<defaults> to: gather_timeout
227
228=back
229
230=back
231
232=cut
233
234# End of autogenerated POD
235###########
236
237
238
239
240=head2 Method new
241
242This is the constructor method for Stem::Gather. It uses the standard
243Stem key/value API with the
244
245=cut
246
247sub new {
248
249 my( $class ) = shift ;
250
251 my $self = Stem::Class::parse_args( $attr_spec, @_ ) ;
252 return $self unless ref $self ;
253
254# return 'Stem::Gather "keys" is not an array reference'
255# unless ref $self->{'keys'} eq 'ARRAY' ;
256
257 $self->restart() unless $self->{'no_start'} ;
258
259 return( $self ) ;
260}
261
262=head2 Method restart
263
264This method is called to start up the gather object when it has
265already gathered all the keys, it has timed out or it was never
266started (the no_start attribute was enabled). It takes no arguments.
267
268=cut
269
270
271sub restart {
272
273 my( $self ) = @_ ;
274
275 $self->{'gathered'} = 0 ;
276
277 $self->{'keys_left'} = { map { $_, 1 } @{$self->{'keys'}} } ;
278
279# TraceStatus "GAT keys '@{$self->{'keys'}}'" ;
280
281 $self->_cancel_timeout() ;
282
283 if ( my $timeout = $self->{'timeout'} ) {
284
285 $self->{'timer_event'} = Stem::Event::Timer->new(
286 'object' => $self,
287 'delay' => $timeout,
288 'hard' => 1,
289 'repeat' => 0 ) ;
290 }
291}
292
293=head2 Method add_keys
294
295This method is passed a list of keys which will be added to the list
296to be watched for by the Stem::Gather object. The new keys are not
297looked for until a call to the C<restart> method is made.
298
299=cut
300
301sub add_keys {
302
303 my( $self, @keys ) = @_ ;
304
305 push @{$self->{'keys'}}, @keys ;
306}
307
308=head2 Method gathered
309
310This method is called with a list of keys that are gathered. The keys
311that haven't been gathered before are marked as gathered. If there are
312no more keys to be gathered, the method in the C<gathered_method>
313attribute is called in the owner object. You have to call the
314C<restart> method on this gather object to use it again.You can pass
315this methods keys that have been gathered or are not even in the list
316to be gathered and they are ignored.
317
318=cut
319
320sub gathered {
321
322 my( $self, @keys ) = @_ ;
323
324# TraceStatus "gathered: @keys" ;
325
326 return if $self->{'gathered'} ;
327
328 delete @{$self->{'keys_left'}}{@keys} ;
329
330 return if keys %{$self->{'keys_left'}} ;
331
332 $self->_cancel_timeout() ;
333 $self->{'gathered'} = 1 ;
334
335 my $method = $self->{'gathered_method'} ;
336
337# TraceStatus "gathered done: calling $method" ;
338
339 return $self->{'object'}->$method() ;
340}
341
342sub timed_out {
343
344 my( $self ) = @_ ;
345
346 $self->_cancel_timeout() ;
347
348 my $method = $self->{'timeout_method'} ;
349 $self->{'object'}->$method() ;
350
351 return ;
352}
353
354sub _cancel_timeout {
355
356 my( $self ) = @_ ;
357
358 if ( my $timer = $self->{'timer_event'} ) {
359 $timer->cancel() ;
360
361 delete $self->{'timer_event'} ;
362 }
363}
364
365=head2 Method
366
367This method B<must> be called if the owner object is being shut down or
368destroyed. It will cancel any pending timeout and break the link back
369to the owner object. The owner object can then be destroyed without
370leaking memory.
371
372=cut
373
374sub shut_down {
375
376 my( $self ) = @_ ;
377
378 $self->_cancel_timeout() ;
379
380 delete $self->{'object'} ;
381}
382
3831 ;