1 |
joko |
1.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; |