| 1 | #!/usr/bin/perl -w | 
| 2 | # $Id: followtail.perl,v 1.8 2001/05/07 12:23:04 rcaputo Exp $ | 
| 3 |  | 
| 4 | # This program tests Wheel::FollowTail.  The FollowTail wheel provides | 
| 5 | # a reusable "tail -f" behavior for drivers and filters. | 
| 6 |  | 
| 7 | # NOTE: sessions.perl, objsessions.perl, and packagesessions.perl have | 
| 8 | # better comments for the basic stuff. | 
| 9 |  | 
| 10 | use strict; | 
| 11 | #use lib '..'; | 
| 12 |  | 
| 13 | #sub POE::Kernel::ASSERT_DEFAULT () { 1 } | 
| 14 | #sub POE::Kernel::TRACE_DEFAULT () { 1 } | 
| 15 |  | 
| 16 | use POE qw(Wheel::FollowTail Driver::SysRW Filter::Line Wheel::ReadWrite); | 
| 17 | use IO::File; | 
| 18 |  | 
| 19 | #============================================================================== | 
| 20 | # used to keep track of file names | 
| 21 | #my @names; | 
| 22 | # the names of sessions to create | 
| 23 | #my @numbers = qw(one two three four five six seven eight nine ten); | 
| 24 |  | 
| 25 | #------------------------------------------------------------------------------ | 
| 26 | # Create twenty sessions: ten log generators and ten log followers. | 
| 27 | # The generators periodically write a line of information to their | 
| 28 | # respective logs.  The followers detect that the logs have new | 
| 29 | # information and display it. | 
| 30 |  | 
| 31 | #for my $j (0..9) { | 
| 32 | # call the sessions by name | 
| 33 | #my $i = $numbers[$j]; | 
| 34 | # create temporary filenames | 
| 35 | my $name = 'c:\var\home\amo\.mjamcmd'; | 
| 36 |  | 
| 37 | ### create a log follower | 
| 38 | POE::Session->new | 
| 39 | ( '_start' => sub | 
| 40 | { my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP]; | 
| 41 | #$heap->{'id'} = $i; | 
| 42 | # try to open the file | 
| 43 | if (defined(my $handle = IO::File->new("<$name"))) { | 
| 44 | # start following the file's tail | 
| 45 | #$handle->blocking(1); | 
| 46 | $heap->{'wheel'} = POE::Wheel::FollowTail->new | 
| 47 | ( 'Handle' => $handle,                  # follow this handle | 
| 48 | #'Driver' => POE::Driver::SysRW->new,  # use sysread to read | 
| 49 | #'Filter' => POE::Filter::Line->new,   # file contains lines | 
| 50 | 'InputEvent' => 'got a line',         # input handler | 
| 51 | 'ErrorEvent' => 'error reading',      # error handler | 
| 52 | 'PollInterval' => 1, | 
| 53 | 'SeekBack' => 5, | 
| 54 | ); | 
| 55 | print "reader started", "\n"; | 
| 56 | use Data::Dumper; | 
| 57 | print Dumper($heap->{'wheel'}); | 
| 58 | } | 
| 59 | # could not read the file | 
| 60 | else { | 
| 61 | print "Reader $heap->{'id'} can't open $name for reading: $!\n"; | 
| 62 | } | 
| 63 | }, | 
| 64 | # close and destroy the log filehandle | 
| 65 | '_stop' => sub | 
| 66 | { my $heap = $_[HEAP]; | 
| 67 | delete $heap->{'wheel'}; | 
| 68 | print "Reader $heap->{'id'} has stopped.\n"; | 
| 69 | }, | 
| 70 | # error handler | 
| 71 | 'error reading' => sub | 
| 72 | { my ($heap, $operation, $errnum, $errstr) = @_[HEAP, ARG0, ARG1, ARG2]; | 
| 73 | print( "Reader ",$heap->{'id'}, | 
| 74 | " encountered $operation error $errnum: $errstr.\n" | 
| 75 | ); | 
| 76 | # removes the session's purpose to live | 
| 77 | delete $heap->{'wheel'}; | 
| 78 | }, | 
| 79 | # input handler | 
| 80 | 'got a line' => sub | 
| 81 | { my $line_of_input = $_[ARG0]; | 
| 82 | # just display the input | 
| 83 | print "got line: "; | 
| 84 | print $line_of_input, "\n"; | 
| 85 | }, | 
| 86 |  | 
| 87 | # To catch strange events. | 
| 88 | _default => | 
| 89 | sub { | 
| 90 | warn "default caught $_[ARG0] with (@{$_[ARG1]})"; | 
| 91 | my $i = 0; | 
| 92 | while (1) { | 
| 93 | my @xyz = map { defined($_) ? $_ : '(undef)' } caller($i++); | 
| 94 | $xyz[-1] = unpack 'B*', $xyz[-1]; | 
| 95 | last unless @xyz; | 
| 96 | warn "$i: @xyz\n"; | 
| 97 | } | 
| 98 | return 0; | 
| 99 | }, | 
| 100 | ); | 
| 101 | #} | 
| 102 |  | 
| 103 | #------------------------------------------------------------------------------ | 
| 104 | # This session is just a busy loop that prints a message every half | 
| 105 | # second.  It does this to ensure that the other twenty sessions are | 
| 106 | # not blocking while waiting for input. | 
| 107 |  | 
| 108 | POE::Session->new | 
| 109 | ( _start => sub | 
| 110 | { my ($kernel, $session) = @_[KERNEL, SESSION]; | 
| 111 | $kernel->post($session, 'spin a wheel'); | 
| 112 | }, | 
| 113 | 'spin a wheel' => sub | 
| 114 | { my $kernel = $_[KERNEL]; | 
| 115 | print "*** spin! ***\n"; | 
| 116 | $kernel->delay_add('spin a wheel', 2); | 
| 117 | }, | 
| 118 | ); | 
| 119 |  | 
| 120 | #============================================================================== | 
| 121 | # Run the kernel until all the sessions die (SIGINT, most likely). | 
| 122 | # When done, unlink the temporary files in @names. | 
| 123 |  | 
| 124 | $poe_kernel->run(); | 
| 125 |  | 
| 126 | # The temporary files are unlinked out here because some systems | 
| 127 | # (notably DOSISH ones) don't allow files to be unlinked while they | 
| 128 | # are open. | 
| 129 |  | 
| 130 | #unlink @names; | 
| 131 |  | 
| 132 | exit; |