perl – 为什么Hypnotoad的热部署会重新运行旧的http请求?
简而言之:
当我对Hypnotoad进行热部署时,新服务器会立即处理大量已由前一服务器处理的HTTP请求. 如果已呈现响应但线程仍在进行某些处理,Mojo / Hypnotoad是否会保留请求,直到处理停止为止?我是否需要告诉服务器HTTP请求已解决? 长版: 我们正在处理通过一系列州进展的工作. 脚本作业是操纵一些数据..进行数据库更新,编辑文件,发送邮件. 为了使事情继续前进,当它收到HTTP请求时,它会检查收到的数据.如果数据看起来很好,它会立即向调用者发送200响应,然后继续执行更耗时的任务. (我猜这是根本原因) 当我热部署时 – 通过重新运行启动脚本(运行’localperl / bin / hypnotoad $RELDIR / etc / bki / bki.pl’) – 已经处理的一些请求被发送到新服务器并重新处理. 为什么这些旧的交易仍由原始服务器持有?许多人已经很久没有完成了! 这是我正在做的一些伪代码: get '/jobStateChange/:jobId/:jobState/:jobCause' => sub { my $c =shift; my $jobId = $c->stash("jobId"); return $c->render(text => "invalid jobId: $jobId",status => 400) unless $jobId=~/^d+$/; my $jobState = $c->stash("jobState"); return $c->render(text => "invalid jobState: $jobState",status => 400) unless $jobState=~/^d+$/; my $jobCause = $c->stash("jobCause"); return $c->render(text => "invalid jobCause: $jobCause",status => 400) unless $jobCause=~/^d+$/; my $jobLocation = $c->req->param('jobLocation'); if ($jobLocation){ $jobLocation = $ENV{'DATADIR'} . "/jobs/" . $jobLocation; } unless ( $jobLocation && -d $jobLocation ){ app->log->debug("determining jobLocation because passed job jobLocation isn't useable"); $jobLocation = getJobLocation($jobId); $c->stash("jobLocation",$jobLocation); } # TODO - more validation? would BKI lie to us? return if $c->tx->res->code && 400 == $c->tx->res->code; # return if we rendered an error above # tell BKI we're all set ASAP $c->render(text => 'ok'); handleJobStatusUpdate($c,$jobId,$jobState,$jobCause,$jobLocation); }; sub handleJobStatusUpdate{ my ($c,$jobLocation) = @_; app->log->info("job $jobId,state $jobState,cause $jobCause,loc $jobLocation"); # set the job states in jobs app->work_db->do($sql,undef,@params); if ($jobState == $SOME_JOB_STATE) { ... do stuff ... ... uses $c->stash to hold data used by other functions } if ($jobState == $OTHER_JOB_STATE) { ... do stuff ... ... uses $c->stash to hold data used by other functions } } 解决方法
在请求处理程序返回之前,您的请求将不会完成.例如,这个小应用程序需要5秒钟才能输出“test”:
# test.pl use Mojolicious::Lite; get '/test' => sub { $_[0]->render( text => "test" ); sleep 5 }; app->start; 您的应用的解决方法是在后台进程中运行handleJobStatusUpdate. get '/jobStateChange/:jobId/:jobState/:jobCause' => sub { my $c =shift; my $jobId = $c->stash("jobId"); my $jobState = $c->stash("jobState"); my $jobCause = $c->stash("jobCause"); my $jobLocation = $c->req->param('jobLocation'); ... $c->render(text => 'ok'); if (fork() == 0) { handleJobStatusUpdate($c,$jobLocation); exit; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |