Search code examples
perlfire-and-forget

how to launch multiple fire and forget PHP scripts with Perl?


I currently have a perl script which I am trying to use to launch three (or more) php scripts each with a set of arguments provided from a database:

$sql = "SELECT id,url,added,lasttotal,lastsnapshot,speed,nextsnapshot FROM urls WHERE DATE(NOW()) > DATE(nextsnapshot)  LIMIT 0,3";
$sth = $dbh->prepare($sql);
$sth->execute or print "SQL Error: $DBI::errstr\n";

my ($urlID, $url, $added,$lastTotal,$lastSnapshot,$lastSpeed,$nextsnapshot);

$sth->bind_col(1, \$urlID);
$sth->bind_col(2, \$url);
$sth->bind_col(3, \$added);
$sth->bind_col(4, \$lastTotal);
$sth->bind_col(5, \$lastSnapshot);
$sth->bind_col(6, \$lastSpeed);
$sth->bind_col(7, \$nextsnapshot);

while ($sth->fetch) {
  $myexec = "php /usr/www/users/blah/blah/launch_snapshot.php '$url' $urlID '$added' $lastTotal '$lastSnapshot' $lastSpeed".'  /dev/null 2>&1 &';

  exec ($myexec)     or print  "\n Couldn't exec $myexec: $!";  
} 

I don't care about any results from the PHP scripts, I just need to start them all at once, or with a very small delay.

The fetch works properly and returns three unique sets of values. However, it never seems to get past launching the first php script. I don't get any error messages.

Any help would be most appreciated.


Solution

  • You could use fork or just system for that.

    Using fork:

    foreach($sth->fetch) {
      my $pid = fork();
      if($pid) { # Parent
        waitpid($pid, 0);
      } elsif ($pid == 0) { # A child
        $myexec = "...";
        exec($myexec) or print "\n Couldn't exec $myexec: $!";
        exit(0); # Important!
      } else {
        die "couldn't fork: $!\n";
      }
    }
    

    Using system:

    foreach($sth->fetch) {
      $myexec = "...";
      system($myexec);
    }