http://www.perlmonks.org?node_id=821669


in reply to Time::HiRes strange behavior

tail from GNU coreutils has an option for controlling the sleep time between reads:
-s, --sleep-interval=S with -f, sleep for approximately S seconds (default 1.0) between ite +rations
And if you really want to follow a rapidly growing file (for instance some timing sensitive log without proper timestamps) with a lot finer time resolution than probably you appreciate the File-Tail module from CPAN. This modules adapts its sleep interval to the line-update frequency measured before. (Of course if you don't have control on the buffering at output side, this still won't be better.) An example:

# generate test log file in bash $ while true ; do echo $(( ++i )) ; sleep .1 ; done > test

# little File::Tail demo use Time::HiRes qw( gettimeofday ); use File::Tail; $| = 1; my $tail = File::Tail->new( name => './test', maxinterval => 0.1 ); my $usec; my $sec_since_epoch; my $line; while ( defined( $line = $tail->read() ) ) { ( $sec_since_epoch, $usec ) = gettimeofday(); printf "%d.%d\n", $sec_since_epoch, $usec; }

Replies are listed 'Best First'.
Re^2: Time::HiRes strange behavior
by golden.radish (Initiate) on Feb 06, 2010 at 02:22 UTC
    This is a great suggestion, rubasov, and it works well except for one thing.
    When I use this on a CIFS or SMB mounted filesystem, it reloads (and re-"tails") the entire file each time it changes. On a local filesystem, it works fine. So it looks like I have to port the whole thing over to run locally under Windows. :(
    However, I do appreciate the response, it's definitely helped.
    I've also tried using tail -s with a value less than 1.0, and while it appears to accept the value, it doesn't actually change the behavior in any way I can see.

      Hmm, I never tried to use it on CIFS shares, however this definitely seems to me a bug in SMBFS/CIFS. Have you really tried with both of them? (AFAIK they do not share much of code lines, so it can be that in one of them the bug is not present.)

      After a little googling I found this thread, where someone claims to workaround a similar problem by mounting the CIFS share with the directio mount option. Though I don't know whether this can be recommended in a production system (how stable it is, how much it hurts performance). Anyway you may give it a try.

      Hope that helps.
        Yep, it doesn't work at all without 'directio' as an option at mount time, even just trying to tail from the shell.
        However, I was able to get it to work 99.993% of the time (tested with 20,000+ lines) by altering the File::Tail option 'reset_tail' to 1.
        That provides the expected behavior, for the moment. There are rare occasions when log lines are duplicated, such as when there are more than 9-10 events per second. However that is rare with my data stream, so this will be good enough for now.