0

I have come across a wierd bug that I hope someone can help with. I've tried to provide as much background below without going into too much detail, but am happy to clarify anything confusing.


Im currently working on a web-app that uses Perl for back-end server processing. Basically the user requests some data to be processed and returned from a PostgreSQL database from the browser. Sometimes this takes a short amount of time and I can return the data back to the user before a server timeout error occurs. For larger requests I fork off the back end process and send an email to the user, with the data attached, when it is ready.

Using CGI::Application I have a runmode that calls this sub which forks off the back end process and returns the parent process to a page telling the user that they will receive an email when their data is ready:

sub _emailUserData {

my $self = shift;
my $_user_email = shift;
$self->session->close;     /*Closes the current CGI::Session to prevent an error*/
my $template = $self->load_tmpl( 'sending_u_email.tmpl' , die_on_bad_params=>0 );
my $pid = fork;
if ($pid) {
    $template->param(email_address=>$_user_email);
    return $template->output();
    waitpid $pid, 0;
}
else {
    close STDIN;
    close STDOUT;
    close STDERR;
    my $longProcessHandle = Modules::LongProcess->new();
    $longProcessHandle->dbixSchema($self->dbixSchema);
    $longProcessHandle->emailResultsToUser($_user_email);
}
}

Note:: dbixSchema here is just a database schema object created when cgi is initialized (database connection and database handler) allowing me to connect to the PostgreSQL db, and run queries right in Perl.

Now in this other module LongProcess I have a sub emailResultsToUser that does all the accessing of the database, processing of data and emailing the user (in a stripped down version):

sub emailResultsToUser {

my $self = shift;
my $_user_email = shift;

open(STDERR, ">>/home/xyz.log") || die "Error stderr: $!";
print STDERR "Email to be sent to $_user_email\n";

   my $userData = $self->getData();

   /*Code for generating the email and sending it to user*/
);
}

and in the helper sub:

sub getData {

    my $self=shift;
    my $resultDataTable = $self->dbixSchema->resultset('DataTable')->search(
    {},
    {
                columns => [qw/columnA columnB columnC/]
    }
    );
    my @results = $resultDataTable->all;

    /*Code to process reults and store it into a hash called %dataHash */

   return \%dataHash;
}

The problem

For whatever reason getData gets called and everything runs smoothly (as inidicated by various print statements to the error log - which I have omitted) but the subroutine never returns to the caller (which is emailResultsToUser) and thus emailResultsToUser never finishes. getData just hangs right at its return statement with no inidication of an error. Im able to print the results returned from the database and I can verify that the data processing takes place and that a %resultHash is made.

Im not sure exactly why this happens. I've managed to nail it down to possibly connecting to the postgreSQL database. If I don't pass dbixSchema to the child (while yes, Ill get an error that its not defined in the child) emailResultsToUser will complete if I wrap my $userData = $self->getData(); in an eval{}. Even if I don't pass the dbixSchema object from the parent and create a new one in the child, the same "error" happens.

Any thoughts?

dnak
  • 138
  • 1
  • 1
  • 9
  • 1
    DBIx refers to an entire namespace for DBI extensions, DBIx::Class refers to the ORM. The preferred shortname is DBIC. I don't have enough information to answer your question, but from what you describe, it's possible your query is taking a very long time and your cgi is timing out. Or you are not waiting long enough for your query to return. Isolate the query and run it in with DBIC_TRACE=1. Are you getting any errors in your webserver error log? are you using `use strict;` and `use warnings;`? If you are still using CGI: `use CGI::Carp qw(fatalsToBrowser warningsToBrowser);` – mikew Oct 17 '13 at 14:56
  • I definitely have `use strict;` and `use warnings;` (as I always do when writing Perl code). As a matter of fact I did figure out a work around to the problem after all, but would definitely go back and try debugging the old approach while checking for the errors you've suggested for learning purposes. Many thanks for your input and suggestions @mikew . – dnak Oct 17 '13 at 23:19

0 Answers0