1

I am using AsyncTimeout perl package to invoke a process asynchronously with timeout in seconds. The process is taking more time to complete, it is returning "Timed out" msg only after completing the process.

Is there a way to stop the process and return timed-out?

brian d foy
  • 129,424
  • 31
  • 207
  • 592
Haripriya
  • 11
  • 2
  • Is this on Windows? You could also try [IPC::Run](https://metacpan.org/pod/IPC::Run) – Håkon Hægland Feb 02 '21 at 09:25
  • Can you show a minimal example of your code? See [mcve] for more information.. – Håkon Hægland Feb 02 '21 at 09:32
  • Yes, it is on windows. – Haripriya Feb 02 '21 at 09:46
  • Sample Code: my $timeout = "10"; my $retval = AsyncTimeout->new(sub {fun1()}, $timeout, "Timed out"); while (defined $retval) { my $e; if ($retval->ready()) { } } – Haripriya Feb 02 '21 at 09:50
  • Can you try the example in [How to catch timeout exception with IPC::Run on Windows 10?](https://stackoverflow.com/a/65894287/2173773) ? – Håkon Hægland Feb 02 '21 at 09:53
  • As I am trying with Asynchronous timed out, IPC will not work. Thanks for your suggestion – Haripriya Feb 02 '21 at 09:55
  • Yes, I can see from the documentation that it has no support for running sub routines asynchronously on Windows.. If that is what you mean? – Håkon Hægland Feb 02 '21 at 10:02
  • So, because of subroutine, it is not working. If it can be directly with the block, it will work. Is it correct? – Haripriya Feb 02 '21 at 10:07
  • Is that a long running computation? The timeout in AsyncTimeout is implemented using `alarm()` which is not automatically delivered on windows. If you can call `sleep(1)` from time to time (in your worker callback) you loose a second but the alarm will get caught. – clamp Feb 02 '21 at 11:52
  • Yes, it is a long running computation. Can you ellaborate on which place you are suggesting to add sleep – Haripriya Feb 02 '21 at 12:21

1 Answers1

1

The timeout in AsyncTimeout is implemented using alarm() which is not automatically delivered on windows. If you can call sleep() from time to time (in your worker callback) the alarm will get caught.

use strict;
use warnings;
use Async;

my $proc = AsyncTimeout->new(sub{for (1..10000){
                                          print "count: $_\n";
                                          sleep(0);
                                          }
                                 },
                              1,
                              "my timeout\n");

while (defined $proc) {
  print "Main program:  The time is now ", scalar(localtime), "\n";
  my $e;
  if ($proc->ready) {
    if ($e = $proc->error) {
      print "Something went wrong.  The error was: $e\n";
    } else {
      print "The result of the computation is: ", $proc->result, "\n";
    }
    undef $proc;
  }
  # The result is not ready; we can go off and do something else here.
  sleep 1; # One thing we could do is to take nap.
}
print "main process continues\n";

prints

count: ...
count: 5555
The result of the computation is: my timeout

main program continues

This works with strawberry 5.22 and 5.32. If you have to do long running system calls this approach will be of no use.

clamp
  • 2,552
  • 1
  • 6
  • 16
  • Thanks for the suggestion. But, with the above approach, it would come out with time out, but still $proc is undefined, as the async process is running in background or stopped – Haripriya Feb 02 '21 at 13:05