views:

171

answers:

3

I am wondering if it is possible, and if so how, one could create a perl script that constantly monitors a file/db, and then call a subroutine to perform text processing if the file is changed. I'm pretty sure this would be possible using sockets, but this needs to be used for a webchat application on a site running on a shared host, and I'm not so sure sockets would be allowed on it.

The basic idea is:

  • create a listener for a chat file/database
  • when the file is updated with a new message, call a subroutine
  • the called subroutine will send the new message back to the browser to be displayed

Thanks in advance.

+8  A: 

Many operating systems run a service that allows applications to register a request to be notified when a file or path has been updated. This is generally called a File Alteration Monitor. See the linked wikipedia page for some systems available. Recent linux systems use Inotify, previously Dnotify or gamin were used. OS X uses FSEvents. Windows has a similar system. I don't know of any module or mechanism that works cross platform for all these systems, but there are specific modules available on CPAN, such as SGI::FAM and File::Tail::FAM.

kbenson
Hmm, File::Tail::FAM seems to be what I'm looking for, I'l look into it. Thanks.
Hussain
[File::ChangeNotify](http://search.cpan.org/perldoc/File::ChangeNotify) hopes to be a general-purpose cross-platform one of these, but as of now it only has backends for Inotify, BSD KQueues, and a fallback polling method (`stat` all of the files and dirs periodically). No Win32, no FAM. :(
hobbs
A: 

I'd do this with a cron job and a Makefile that invoked a Perl script. The handy thing is that you get the Perl script's atime automatically as the timestamp to compare against, since the script's atime is updated when it is invoked.

Ether
This seems promicing, but alas, the site is on a shared host.
Hussain
A: 
use POE qw(Wheel::FollowTail);
POE::Session->create(
    inline_states => {
      _start => sub {
        $_[HEAP]{tailor} = POE::Wheel::FollowTail->new(
          Filename => "/var/log/thttpd.log",
          InputEvent => "got_log_line",
          ResetEvent => "got_log_rollover",
        );
      },
      got_log_line => sub {
        #print "Log: $_[ARG0]\n";
        parseline($_[ARG0]);
      },
      got_log_rollover => sub {
        #print "Log rolled over.\n";
      },
    }
  );

POE::Kernel->run();
exit;

#parseline()...etc.
superkuh
Just wondering, is that module included in a standard perl instal, or is it from CPAN?
Hussain