benlaw has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks, I am trying to monitor directory through POE, I download POE-Component-DirWatch and try to monitor win32 directory

c:\> C:\temp\

however, there is no response whatever I add any file
#! perl -w # #$Id: dirwatch,v 1.3 2002/07/04 20:13:24 eric Exp $ use strict; use POE qw(Component::DirWatch); my $dir = shift or die "usage: $0 directory\n"; my $intv = shift || 1; print "$dir\n"; POE::Session->create( inline_states => { _start => \&_start, }, args => [ $dir, $intv ], ); $poe_kernel->run(); exit 0; #################### sub _start { my ($kernel, $dir, $intv, $rex) = @_[KERNEL, ARG0..ARG2]; POE::Component::DirWatch->spawn( Directory => $dir, PollInterval => $intv, Filter => sub { $_[0] =~ /\.gz$/ && -f $_[1] }, Callback => \&gotfile, ); } #################### sub gotfile { print "$dir\n"; my ($file, $pathname) = @_[ARG0, ARG1]; print scalar(localtime), " $file ($pathname)\n"; }

Replies are listed 'Best First'.
Re: Problem with POE-Component-DirWatch
by runrig (Abbot) on Mar 12, 2006 at 17:24 UTC
    I get the same behavior. I suspect that it's due to POE::Component::DirWatch's poll routine not opening the directory on every poll, but opening it once and then rewinding it after that. New files never get processed, just the first list of files that were returned on the first poll. I don't know whether to consider this a bug in the POE::Component::DirWatch or Win32's implementation of rewinddir. You could patch the poll routine to open the directory on every poll.

    Update: Better yet, it would probably be best to modify the module to use Win32::ChangeNotify on Windows.

    Update: Win32::ChangeNotify followup here

      Actually talking un*x, if you open a file, do stuff and at some point rewind it, i would not like the system to close and reopen the descriptor for me; they are many reasons: many passes onthe same file, descriptor sharing with children...etc I would expect the same behaviour for dir handles; this means rewinding makes you look at the same structure again... % perldoc -f rewinddir rewinddir DIRHANDLE Sets the current position to the beginning of the directory for the "readdir" routine on DIRHANDLE. it does not say the handle is closed and then reopened... actually a poor man's rewinddir will do just that... from what you say it seems this time that it is perl on unix that does it wrong (poorly)...this should be filed as a bug
Re: Problem with POE-Component-DirWatch
by rcaputo (Chaplain) on Mar 12, 2006 at 19:01 UTC

    Nice test case. Have you approached the module's author with it?

Re: Problem with POE-Component-DirWatch
by insaniac (Friar) on Mar 13, 2006 at 11:24 UTC

    You're problem is really obvious:

    Filter => sub { $_[0] =~ /\.gz$/ && -f $_[1] },
    remove this (or make a better filter) from your code, and it will work better ;-)
    I've tested the above code in Windows and Linux, without the Filter-line, all works well :)


    to ask a question is a moment of shame
    to remain ignorant is a lifelong shame

      I tested the code also (how did you test it?). While the program was running, I created a file with a name ending in ".gz", and the module did not detect it. In debugging the module, I found that the same list of files was being processed over and over, without the new file ever being in the list, BEFORE the filtering even took place. I suspect it's a difference in the way rewinddir behaves on Win32 vs. *nix (instead of opening the directory with opendir, it just rewinds the previously opened directory handle and then reads the files again from the same handle). And if your test was valid, then maybe it also depends on the version of Windows and/or perl?
        Thanks for all monks! I try to modify the filter to
        Filter => sub { $_[0] =~ /.txt$/ && -f $_[1] },
        then I re-run, it print the following message repeatly until i del file test.txt manually
        Tue Mar 14 06:41:06 2006 test.txt (C:\temp\test.txt) Tue Mar 14 06:41:06 2006 test.txt (C:\temp\test.txt)
        however I try paste new_test.txt to c:\temp\, it seems no response (May be the same with runrig) my perl version is "v5.8.4 built for MSWin32-x86-multi-thread"