我无法在Laravel Framework 4.2中中断Controller方法。 我有一个查询,它遍历一个包含~100K记录的表,并检查几个不同的属性,将它们重新分配到其他几个表中。
我想从前端故意中断这个循环。我在控制器类和Session变量中尝试了一个变量都无济于事。
我还有一个进度条,显示循环的状态。我已经把 它下方有一个按钮,用于中止该方法。
class TeilnehmerController extends IXPController {
public $abort;
public function recheckfailedbatch(){
Session::forget('ALL');
Session::forget('status');
Session::forget('progress');
Session::forget('abort');
ini_set('memory_limit', '-1');
ini_set('max_execution_time', '600');
$anzahl['ALL']= anforderung_mangelhaft::all()->count();
Session::set('ALL', $anzahl['ALL']);
Session::set('status', true);
$progress = "0";
$all_fails = anforderung_mangelhaft::all();
foreach ($all_fails as $fail){
if ($this->abort){
break(2);
}
$progress++;
Session::set('progress', $progress);
Session::save();
// doing more secret fancy stuff here
}
Session::set('status', false);
Session::forget('abort');
Session::save();
return Redirect::back()->with('successMessage', "Done.");
}
public function recheckfailedbatchstatus(){
$status = Session::get('status');
$progress = Session::get('progress');
$all= Session::get('ALL');
if ($all != 0){
$percent = sprintf("%1\$.2f",$progress / $all * 100);
}
else{
$percent = 0;
}
return Response::json(array('status' => $status, 'percent' => $percent));
}
public function recheck_abort(){
#$this->abort = true;
Session::set('abort', true);
Session::save();
return dump($this->abort);
}
}
@extends('layouts.default')
@section('subview')
<div>
<h2 class="mb20">mangelhafte Anforderungen</h2>
<ul id="sectionsubnav">
<li>
<a href="{{action('TeilnehmerController@recheckfailedbatch')}}" ><i class="icon-refresh"></i>Erneute Prüfung</a>
<a href="#collapseSuche" data-toggle="collapse" aria-expanded="false" aria-controls="collapseSuche"><i class="icon-search"></i>Detailsuche</a>
</li>
</ul>
@include('components.sysmessages')
@if(Session::get('status'))
<div class="well well-lg">
<h4>Prüfung läuft</h4>
<div class="progress">
<div id="progress-bar" class="progress-bar progress-bar-striped active" role="progressbar"
aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:0%">
</div>
</div>
<a href="{{ action('TeilnehmerController@recheck_abort') }}" onClick="return confirm('Diese Aktion kann nicht rückgängig gemacht werden. Sind Sie sicher?');" id="abort" class="btn btn-danger btn-lg" role="button"><i class="icon-remove"></i>Abbrechen</a>
</div>
@endif
<!-- some more fancy content -->
@stop
@section('bodybottomscripts')
@parent
<script>
$(document).ready(function() {
var element = $("#progress-bar");
var test = setInterval( function(){ bar_progress() }, 500);
function bar_progress() {
$.get( "mangelhaft/recheck-status", function( data ) {
if (data['status'] == false){
clearInterval(test);
}
element.text(data['percent'] + '%');
element.attr("aria-valuenow", data['percent']);
element.width(data['percent'] + '%');
});
}
</script>
@stop
是否可以按照预期的方式进行?我还读过laravel中的队列。我宁愿实施队列来做那些事吗?
答案 0 :(得分:0)
前端不知道后端,不能影响正在运行的脚本。这是因为前面只有在完成后才从后面获得输出。
您需要重新考虑您的方法,并可能使用ajax来检索您的数据,然后客户端代码可以决定是否与您的API联系,视具体情况而定。
答案 1 :(得分:0)
首先,我认为您不能只使用$this->abort
来检查会话。将其替换为Session::get('abort')
,看看它是否有效。这两个函数可能在两个不同的请求中起作用,它们与类成员或内存中的任何其他内容没有任何关系(除了一些例外,请参阅进一步说明)。
您可以使用文件来指示正在运行的脚本的中止。在recheck_abort
中,创建一个空文件(最好使用操作系统的temp
目录)。然后检查是否存在该文件,而不是检查$this->abort
。使用此文件执行与使用会话unlink
文件相同的操作(如果它在recheckfailedbatch
的最开始时存在,并且最后也存在unlink
。
另一个解决方案是使用shared memory。这有点棘手,但可以正确完成工作。
我认为会话在请求开始时被读取,并且它不会反映当前正在运行时进一步请求所做的更改。我没有检查Laravel源代码以确定,但在处理请求时似乎会话变量驻留在内存中。
另一种解决方法是搜索在处理请求时如何刷新会话。这可能意味着要检查Laravel源代码,但检查它是否非常简洁。