Вспомогательная подпрограмма Perl не возвращается в разветвленном процессе
Я наткнулся на странную ошибку, с которой, я надеюсь, кто-то может помочь. Я постарался представить как можно больше информации, не вдаваясь в подробности, но с удовольствием проясню что-то непонятное.
В настоящее время я работаю над веб-приложением, которое использует Perl для обработки внутреннего сервера. В основном пользователь запрашивает некоторые данные для обработки и возврата из базы данных PostgreSQL из браузера. Иногда это занимает немного времени, и я могу вернуть данные пользователю до того, как произойдет ошибка тайм-аута сервера. Для больших запросов я отключаю серверный процесс и отправляю электронное письмо пользователю с прикрепленными данными, когда он будет готов.
С помощью CGI::Application
У меня есть runmode, который вызывает эту подпрограмму, которая разветвляет внутренний процесс и возвращает родительский процесс на страницу, сообщающую пользователю, что он получит электронное письмо, когда его данные будут готовы:
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 - это просто объект схемы базы данных, созданный при инициализации cgi (подключение к базе данных и обработчик базы данных), позволяющий мне подключаться к базе данных PostgreSQL и выполнять запросы прямо в Perl.
Теперь в этом другом модуле LongProcess
У меня есть саб emailResultsToUser
который осуществляет весь доступ к базе данных, обработку данных и отправку электронной почты пользователю (в урезанном виде):
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*/
);
}
и в вспомогательной суб:
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;
}
Эта проблема
Для любой причины getData
вызывается, и все работает гладко (как указано различными инструкциями print в журнале ошибок - который я пропустил), но подпрограмма никогда не возвращается вызывающей стороне (которая является emailResultsToUser
) и поэтому emailResultsToUser
никогда не заканчивается getData
просто висит прямо в своем операторе возврата без указания ошибки. Я могу распечатать результаты, возвращенные из базы данных, и я могу убедиться, что обработка данных происходит и что %resultHash
сделан.
Я не уверен точно, почему это происходит. Мне удалось связать его с возможностью подключения к базе данных postgreSQL. Если я не передам dbixSchema ребенку (хотя да, я получу ошибку, которая не определена для ребенка) emailResultsToUser
будет завершено, если я заверну my $userData = $self->getData();
в eval{}
, Даже если я не передам объект dbixSchema от родителя и не создам новый в дочернем объекте, произойдет та же самая "ошибка".
Какие-нибудь мысли?