我遇到了一个奇怪的错误,希望有人能提供帮助。我试图在下面提供尽可能多的背景,但不涉及太多细节,但很高兴澄清任何令人困惑的事情。
我目前正在开发一个使用 Perl 进行后端服务器处理的网络应用程序。基本上,用户请求从浏览器的 PostgreSQL 数据库中处理和返回一些数据。有时这需要很短的时间,我可以在服务器超时错误发生之前将数据返回给用户。对于较大的请求,我会分叉后端流程,并在准备好后向用户发送一封电子邮件,并附上数据。
使用CGI::Application
我有一个运行模式,它调用这个子进程,它分叉后端进程并将父进程返回到一个页面,告诉用户他们将在数据准备好时收到一封电子邮件:
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);
}
}
注意:这里的 dbixSchema 只是 cgi 初始化时创建的数据库模式对象(数据库连接和数据库处理程序),允许我连接到 PostgreSQL 数据库,并直接在 Perl 中运行查询。
现在在另一个模块中,LongProcess
我有一个子程序emailResultsToUser
,它可以完成对数据库的所有访问、数据处理和向用户发送电子邮件(在精简版中):
子 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
,都会调用并且一切运行顺利(如错误日志中的各种打印语句所示 - 我已省略),但子例程永远不会返回到调用者(即emailResultsToUser
),因此emailResultsToUser
永远不会完成。getData
只是挂在它的 return 语句上,没有任何错误的迹象。我能够打印从数据库返回的结果,并且我可以验证数据处理是否发生并且 a%resultHash
已完成。
我不确定为什么会发生这种情况。我已经设法将其确定为可能连接到 postgreSQL 数据库。如果我不将 dbixSchema 传递给孩子(是的,我会收到一个未在孩子中定义的错误),emailResultsToUser
如果我my $userData = $self->getData();
将eval{}
. 即使我没有从父级传递 dbixSchema 对象并在子级中创建一个新对象,也会发生相同的“错误”。
有什么想法吗?