我正在使用Laravel 4.2
。
我正在做一个用户上传视频的项目。为了让上传的视频对所有类型的设备都可用,我使用php-ffmpeg
包来transcode
。转码过程很耗时,所以我决定将其移到后台,为此我已经使用Amazon SQS
实现了队列机制。
我已经在queue.php
文件中配置了SQS
驱动程序和密钥、密钥、URL以及区域。
仅出于测试目的,我在Routes.php
中添加了以下代码。
Route::get('/testasync/{id}', function($id){
Queue::push(function($job) use ($id) {
try{
$video_rel = VideoRel::find($id);
$video_rel->delete();
} catch(Exception $ex){
}
$job->delete();
});
return "hello 1234 world " . $id;
});
因此,每当我向http://mydomainname/testasync/{id}
发出get请求时,它都会向队列推送一条消息,以便从特定模型中删除该特定记录。
令人惊讶的是,我发现队列将NOT执行,直到我在服务器上执行queue listener
为止。
如果我需要在服务器上做一些操作(例如部署新代码等),该怎么办?在这种情况下,我必须停止侦听器。
此外,我发现的另一个困难是,每当我重新执行侦听器时,它都试图执行所有作业。
例如,我对Id 1和2提出了两个Get请求。所以这两条记录都被删除了。现在我出于某种原因停止了侦听器,然后再次请求Id 3。现在,记录3不会被删除,直到我使用php artisan queue:listen
执行listner,如果我执行它,它会抛出2个错误,即method delete called on non-object for Id 1 and 2
;并删除Id为3的记录。
我不知道为什么会发生这种情况,因为已经执行的作业必须删除。
有人能找到解决方案吗??
最好从代码中执行监听器,并在作业完成后停止它
我不确定我是否理解您所期望的内容,但当您执行Queue::push时,您将作业发送到队列,它将只由侦听器执行。如果您没有打开queue:listen命令,它将不会运行。如果希望作业立即执行,则不应将其发送到队列中。
您不需要停止侦听器,您可以在主管进程中运行它,它会在超时后自动重新启动进程。检查此项:http://posts.danharper.me/laravel-queue-supervisor/
现在,在您关闭队列:listen后,它试图执行已经处理的作业,这对我来说真的很奇怪,可能是作业没有被删除(尝试将作业删除移到闭包的开头),但我需要更多信息来帮助您调试。
希望这些信息对你有所帮助。