3 # This file is part of Stem.
4 # Copyright (C) 1999, 2000, 2001 Stem Systems, Inc.
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.
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.
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
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:
24 # Stem Systems, Inc. 781-643-7504
25 # 79 Everett St. info@stemsystems.com
29 package Stem::Gather ;
31 #use Stem::Trace 'log' => 'stem_status', 'sub' => 'TraceStatus' ;
32 #use Stem::Trace 'log' => 'stem_error' , 'sub' => 'TraceError' ;
36 This is a object module used by Stem Cells and objects to detect when
37 a set of asynchronous events have finished. It is constructed by an
38 owner object which then stores it in itselt. Gather objects are
39 initialized with a set of keys to be gathered. When the owner object
40 is notified of an event, it calls the C<gathered> method of the gather
41 object with a list of keys. When all of the keys are gathered, a
42 callback is made to the owner object. An optional timeout is available
43 which will also generate a callback if the keys are not gathered in
50 # $self is the owner object that has already been created
52 my $gather = Stem::Gather->new(
54 'keys' => [qw( msg1 msg2 )]
57 $self->{'gather'} = $gather ;
62 $self->{'gather'}->gathered( 'msg1' ) ;
68 $self->{'gather'}->gathered( 'msg2' ) ;
75 print "we have gathered\n" ;
82 my %class_to_attr_name ;
91 This is the owner object which has the methods that get called when Stem::Gather
92 has either finished gathering all of the keys or it has timed out.
100 This is the list of keys to gather.
104 'name' => 'gathered_method',
105 'default' => 'gather_done',
107 This method is called in the owner object when all of the keys are gathered.
111 'name' => 'no_start',
114 If set, then do not start the gather object upon creation. A call to
115 the C<restart> must be made. This only meaningful if this gather has a
122 This is an optional timeout period (in seconds) waiting for the gather
127 'name' => 'timeout_method',
128 'default' => 'gather_timeout',
130 This method is called in the owner object if the gather timed out
131 before all keys were gathered.
138 # This POD section is autoegenerated. Any edits to it will be lost.
140 =head2 Constructor Attributes for Class Stem::Gather
145 =item * Attribute - B<object>
151 This is the owner object which has the methods that get called when Stem::Gather
152 has either finished gathering all of the keys or it has timed out.
155 =item Its B<type> is: object
157 =item It is B<required>.
161 =item * Attribute - B<keys>
167 This is the list of keys to gather.
170 =item Its B<type> is: list
172 =item It is B<required>.
176 =item * Attribute - B<gathered_method>
182 This method is called in the owner object when all of the keys are gathered.
185 =item It B<defaults> to: gather_done
189 =item * Attribute - B<no_start>
195 If set, then do not start the gather object upon creation. A call to
196 the C<restart> must be made. This only meaningful if this gather has a
200 =item Its B<type> is: boolean
204 =item * Attribute - B<timeout>
210 This is an optional timeout period (in seconds) waiting for the gather
216 =item * Attribute - B<timeout_method>
222 This method is called in the owner object if the gather timed out
223 before all keys were gathered.
226 =item It B<defaults> to: gather_timeout
234 # End of autogenerated POD
242 This is the constructor method for Stem::Gather. It uses the standard
243 Stem key/value API with the
249 my( $class ) = shift ;
251 my $self = Stem::Class::parse_args( $attr_spec, @_ ) ;
252 return $self unless ref $self ;
254 # return 'Stem::Gather "keys" is not an array reference'
255 # unless ref $self->{'keys'} eq 'ARRAY' ;
257 $self->restart() unless $self->{'no_start'} ;
262 =head2 Method restart
264 This method is called to start up the gather object when it has
265 already gathered all the keys, it has timed out or it was never
266 started (the no_start attribute was enabled). It takes no arguments.
275 $self->{'gathered'} = 0 ;
277 $self->{'keys_left'} = { map { $_, 1 } @{$self->{'keys'}} } ;
279 # TraceStatus "GAT keys '@{$self->{'keys'}}'" ;
281 $self->_cancel_timeout() ;
283 if ( my $timeout = $self->{'timeout'} ) {
285 $self->{'timer_event'} = Stem::Event::Timer->new(
293 =head2 Method add_keys
295 This method is passed a list of keys which will be added to the list
296 to be watched for by the Stem::Gather object. The new keys are not
297 looked for until a call to the C<restart> method is made.
303 my( $self, @keys ) = @_ ;
305 push @{$self->{'keys'}}, @keys ;
308 =head2 Method gathered
310 This method is called with a list of keys that are gathered. The keys
311 that haven't been gathered before are marked as gathered. If there are
312 no more keys to be gathered, the method in the C<gathered_method>
313 attribute is called in the owner object. You have to call the
314 C<restart> method on this gather object to use it again.You can pass
315 this methods keys that have been gathered or are not even in the list
316 to be gathered and they are ignored.
322 my( $self, @keys ) = @_ ;
324 # TraceStatus "gathered: @keys" ;
326 return if $self->{'gathered'} ;
328 delete @{$self->{'keys_left'}}{@keys} ;
330 return if keys %{$self->{'keys_left'}} ;
332 $self->_cancel_timeout() ;
333 $self->{'gathered'} = 1 ;
335 my $method = $self->{'gathered_method'} ;
337 # TraceStatus "gathered done: calling $method" ;
339 return $self->{'object'}->$method() ;
346 $self->_cancel_timeout() ;
348 my $method = $self->{'timeout_method'} ;
349 $self->{'object'}->$method() ;
354 sub _cancel_timeout {
358 if ( my $timer = $self->{'timer_event'} ) {
361 delete $self->{'timer_event'} ;
367 This method B<must> be called if the owner object is being shut down or
368 destroyed. It will cancel any pending timeout and break the link back
369 to the owner object. The owner object can then be destroyed without
378 $self->_cancel_timeout() ;
380 delete $self->{'object'} ;