| 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; |