1

I've got an application that invokes a potentially long-running process. I want my program, the caller of this process, to cancel it at any given point and move on to the next entry when a time limit is exceeded. Using Perl's AnyEvent module, I tried something like this:

#!/usr/bin/env perl

use Modern::Perl '2017';
use Path::Tiny;
use EV;
use AnyEvent;
use AnyEvent::Strict;

my $cv = AE::cv;
$cv->begin;  ## In case the loop runs zero times...

while ( my $filename = <> ) {
    chomp $filename;
    $cv->begin;

    my $timer = AE::timer( 10, 0, sub {
        say "Canceled $filename...";
        $cv->end;
        next;
    });

    potentially_long_running_process( $filename );
    $cv->end;
}

$cv->end;
$cv->recv;

exit 0;

sub potentially_long_running_process {
    my $html = path('foo.html')->slurp;
    my @a_pairs = ( $html =~ m|(<a [^>]*>.*?</a>)|gsi );
    say join("\n", @a_pairs);
}

The problem is the long-running processes never time out and get canceled, they just keep on going. So my question is "How do I use AnyEvent (and/or related modules) to time out a long-running task?"

scott8035
  • 424
  • 1
  • 6
  • 15
  • 1
    I think the easiest way is probably forking a child process. – melpomene Nov 19 '17 at 22:33
  • 1
    One example of a forked process, timed in one of possible ways, is in [this post](https://stackoverflow.com/a/45250716/4653379) while one example of using an alarm in [this post](https://stackoverflow.com/questions/44533600/perl-host-to-ip-resolution/44535265#44535265). There is much more out there. – zdim Nov 19 '17 at 22:40
  • How do you define _best_? Fastest to implement, most efficient, easiest to read? The way you have asked your question it's about personal opinion, and we consider that off-topic here. Please [edit] and refine. – simbabque Nov 20 '17 at 09:54

1 Answers1

1

You have not mentioned the platform you are running this script on, but if it is running on *nix, you can use the SIGALRM signal, something like this:

my $run_flag = 1;

$SIG{ALRM} = sub {
    $run_flag = 0;
}

alarm (300);

while ($run_flag) {
    # do your stuff here
    # note - you cannot use sleep and alarm at the same time
}

print "This will print after 300 seconds";
Nilesh
  • 624
  • 1
  • 7
  • 23