Re: DirWatch and TCP Client
hideo <[email protected]>
| Newsgroups | gmane.comp.lang.perl.poe |
|---|---|
| Message-ID | <[email protected]> |
Jeff Eggen (Wed 08/06/08 15:40): > >>> hideo <[email protected]> 06/08/2008 2:51 PM >>> > >We have a few daemons that do just this. My strategy has been to: > > > 1) move the new file to a temp directory > > 2) post the file path (and originating directory if necessary) > > to a general event > > 3) via a dispatch table the appropriate subroutine to process > > the file is invoked. > > >1 and 2 happen in the callback. The relevant path and directory > >info will be available in the ARGs. > > >Has worked like a champ for us. > > >Zach > > Just to clarify things for my sake: 1 and 2 happen in the DirWatch session's file_callback method? And the dispatch table is a hash mapping the identifier for each application to a Client::TCP session object? > > I'm a little unsure of what you mean with 2 & 3. I'm thinking that it would be something like this (excuse the rough mock-code): > > # Create Client::TCP sessions: > > my %dispatch; > foreach ( @queues) > { > $dispatch{$_} = PoCo::Client::TCP->new(); > } > > # PoCo::DirWatch object's file_callback method: > sub file_callback > { > my $file = ...; #read file contents into memory > my $tag = substr($file, 19, 5); #get the identifier > $dispatch{$tag}->{server}->put($file); #send $file to server > } > > Is this what you mean? Yeah, that's pretty close. Here's a stripped down version of how we've done it: # use directories as keys my %dispatch = ( '/path/to/file1' => 'do_this', '/path/to/file2' => 'or_this', ); POE::Session->create ( inline_states => { _start => sub { $_[KERNEL]->alias_set('FP'); }, process => sub { my $event = $dispatch{$_[KERNEL]->alias_list($_[SENDER])}; # send the file path to an event, subroutine, or put it # as you have $_[KERNEL]->yield($event, $_[ARG0]); } } ); POE::Component::DirWatch->spawn( Alias => $dir, # set alias to directory name Directory => $dir, Filter => sub { $_[0] !~ /^\./o && -f $_[1] ? 1 : 0 }, Callback => sub { my $k = $_[KERNEL]; my $tmp_file = "$tmp_dir/$_[ARG0]"; # ARG0 with the file name # move the file to a temp file so DirWatch doesn't process it # multiple times, e.g. via File::Copy, another event as here, etc. if($k->call(@{$meta->{mv_session}}, $_[ARG1], $tmp_file) ){ $k->post(FP => process => $tmp_file); } else{ $k->post(@{$opt->{error_session}}, "Failed to move $_[ARG1] to $tmp_file"); } }, PollInterval => 5, );