user1981275
user1981275

Reputation: 13372

Cannot get apache mod_perl with mpirun to work

I am trying to build a simple web service that runs on an ubuntu machine with apache and mod_perl2. The service runs mpirun and returns the output of the call. I invoke a call of the apache response handler via the web browser. The problem is that the mpirun command seems to hang.

Important: This problem occurs on a server running Ubuntu (12.04.4) with apache, mod_perl and openmpi. When running it on my mac (Macos 10.9.3), it works fine and mpirun returns. On both machines, openmpi is installed in the same version (1.6.5)

Here my mod_perl handler:

package MyHandler;
use Apache2::Const '-compile' => 'OK';

sub handler {
        my $command = "mpirun -np 4 echo test";
        my $out = qx($command);
        print $out;
        return Apache2::Const::OK;
}
1;

The mpirun job does not seem to finish. A ps aux | grep mpirun gives me this:

www-data 24023  0.0  0.1  23600  2424 ?        S    13:02   0:00 mpirun -np 4 echo test

When I do a kilall -9 mpirun, the service comes back with the result.

No errors are written to the apache error log.

Here is what I tried/tested:

Any idea why mpirun would hang in my situation or any idea how I could debug this?

Edit

I tried to use Apache2::SubProcess as suggested by hrunting. Here my code following the simple example from the link:

package MyHandler;
use Apache2::SubProcess ();
use Apache2::Const '-compile' => 'OK';
use Apache2::Request;
use Config;
use constant PERLIO_IS_ENABLED => $Config{useperlio};

sub handler {
    my $r = shift;
    my $command = "mpirun -np 4 echo test";
    my ($in_fh, $out_fh, $err_fh) = $r->spawn_proc_prog($command);
    $r->content_type('text/plain');
    my $output = read_data($out_fh);
    my $error  = read_data($err_fh);
    print "output : $output \n";
    print "error : $error \n";
    return Apache2::Const::OK;
}

# helper function to work w/ and w/o perlio-enabled Perl                                                                                                                                                  
sub read_data {
    my ($fh) = @_;
    my $data;
    if (PERLIO_IS_ENABLED || IO::Select->new($fh)->can_read(10)) {
        $data = <$fh>;
    }
    return defined $data ? $data : '';

}
1;

This does not work for me. When calling the handler from the browser, I get the output:

output :  
error :  

and ps aux tells me that mpirun is not running.

Any further ideas of how I could debug this and get mpirun to work with my configuration?

Upvotes: 3

Views: 318

Answers (3)

hrunting
hrunting

Reputation: 3947

Look at Apache2::SubProcess. When you're running external processes within a mod_perl handler, Apache memory, I/O and process management come into play. Remember, your code is running within Apache itself and is subject to the Apache environment. The Apache2::SubProcess module is designed to make exec()- and system()-style calls work properly under within Apache.

Note that the module documentation outlines caveats for dealing with different Perl configurations.

Upvotes: 1

Leeft
Leeft

Reputation: 3837

Capture::Tiny works for me. I'm not sure it'll work well under mod_perl (it may interact badly with the file handles for the request and response) but it works fine as a regular script:

use Capture::Tiny 'capture';

my ( $stdout, $stderr, $exit ) = capture {
    system( qw(mpirun -np 4 echo test) );
};

print "stdout: $stdout\n";
print "stderr: $stderr\n";
print "exit: $exit\n";

Prints:

stdout: test
test
test
test

stderr:
exit: 0

Upvotes: 0

Sergey Svistunov
Sergey Svistunov

Reputation: 104

Try IPC::Run or IPC::Run3 to run your command.

Upvotes: 0

Related Questions