文章转发自专业的Laravel开发者社区,原文链接:https://learnku.com/laravel/t...创建队列作业时,监听器或订阅者推送时对于队列,您可能会开始认为,一旦分派,队列工作人员如何处理您的逻辑完全取决于您。好吧……并不是说您不能在工作中与队列工作人员进行交互,但通常情况下,即使您这样做了,也没有必要。这个神奇的show操作的出现是因为“InteractsWithQueue”这个trait。.当从队列中拉出排队的作业时,此[CallQueuedListener](https://github.com/laravel/framework/blob/5.8/src/Illuminate/Events/CallQueuedListener.php#L90-L104)将检查是否它在使用InteractsWithQueue特性时,如果是这样,框架将在内部注入底层的“队列作业”实例。这个“任务”实例类似于包装真正的Job类的驱动程序,其中包含队列连接和尝试等信息。背景我将以转码作业为例。这是一个将广播音频文件转换为192kbpsMP3格式的任务。由于这是在自由转码队列中设置的,所以作用有限。检查尝试次数attempts()是第一个被调用的方法。顾名思义,它返回尝试次数。排队的作业总是以尝试开始。此方法旨在与其他方法一起使用...,如fail()或release()(延迟)。为了便于说明,我们会通知用户重试多少次:每次我们尝试在空闲队列中转换(转换代码),我们通知用户我们正在重试多少次,让他可以选择取消未来转换(转换代码)。podcast=$podcast;}/***执行队列作业。**@param\Transcoder\Transcoder$podcast*@returnvoid*/publicfunctionhandle(Transcoder$transcoder){//告诉用户我们重试了多少次if($this->attempts()>1){$this->podcast->publisher->notify(newRetryingPodcastTranscode($this->podcast,$this->attempts());}$transcoded=$this->transcoder->setFile($event->podcast)->格式('mp3')->bitrate(192)->start();//将转码后的播客与原始播客相关联$this->podcast->transcode()->associate($transcoded);//通知播客发布者他的播客已经准备好了好吧$this->publisher->notify(newPodcastTranscoded($this->podcast));}}告诉用户我们要重试几次,这在逻辑上很有用抢先失败,让用户(或开发people)来检查哪里出了问题,当然你可以做更多当然,这个例子只是为了说明。删除作业队列第二种方法是delete()。正如您可能猜到的那样,您可以从队列中删除当前的“队列作业”。当排队的Job或Listener由于多种原因在排队后不应该被处理时,这会很方便,例如,考虑这种情况:发布者在转码发生之前出于任何原因(例如TOS冲突)上传播客是停用,我们不应该处理播客。我们将在前面的示例中添加此代码:\Queue\InteractsWithQueue;使用Illuminate\Foundation\Bus\Dispatchable;使用App\Notifications\RetyingPodcastTranscode;类TranscodePodcast{使用Dispatchable、InteractsWithQueue、Queueable、SerializesModels;/***转码器实例**@var\App\Podcast*/protected$podcast;/***创建一个新的转码播客实例。**@param\App\Podcast$podcast*@returnvoid*/publicfunction__construct(Podcast$podcast){$this->podcast=$podcast;}/***执行队列作业。**@param\Transcoder\Transcoder$podcast*@returnvoid*/publicfunctionhandle(Transcoder$transcoder){//如果发布者已经被停用,请删除这个队列作业if($this->podcast->publisher->isDeactivated()){$this->delete();}//告诉用户我们重试了多少次if($this->attempts()>1){$this->podcast->publisher->notify(newRetryingPodcastTranscode($this->podcast,$this->attempts());}$transcoded=$this->transcoder->setFile($event->podcast)->format('mp3')->bitrate(192)->start();//关联转码后的播客原始播客$this->podcast->transcode()->associate($transcoded);//通知发布者他的播客播客准备就绪$this->publisher->notify(newPodcastTranscoded($this->podcast));如果您需要删除可能已删除的模型上的作业,您可能需要设置[$deleteWhenMissingModels](https://laravel.com/docs/5.8/queues#ignoring-missing-models)为true以避免处理不存在的失败队列作业。当您需要控制工件逻辑时,这非常非常方便,因为使用空的“返回”语句会将“作业”标记为成功完成。您可以强制排队的作业失败,希望有一个例外,允许处理程序在可能的情况下稍后重试。这使您可以更好地控制作业失败时的任何情况,并且您还可以使用“failed()”方法,它允许您在失败后执行任何干净的操作,例如通知用户或删除某些内容。在此示例中,如果由于任何原因(例如CDN关闭时)无法从存储中检索播客,作业将失败并出现自定义异常。podcast=$podcast;}/***执行队列作业。**@param\Transcoder\Transcoder$podcast*@returnvoid*/publicfunctionhandle(Transcoder$transcoder){//如果发布者已经被停用,请删除这个队列作业if($this->podcast->publisher->isDeactivated()){$this->delete();}//如果无法从存储中检索播客,我们将失败。如果($this->podcast->fileDoesntExists()){$this->fail(newPodcastUnretrievable($this->podcast));}//告诉用户我们重试了多少次if($this->attempts()>1){$this->podcast->publisher->notify(newRetryingPodcastTranscode($this->podcast,$this->attempts());}$transcoded=$this->transcoder->setFile($event->podcast)->format('mp3')->bitrate(192)->start();//关联转码后的播客原始播客$this->podcast->transcode()->associate($transcoded);//通知播客的发布者他的播客已经准备好$this->publisher->notify(newPodcastTranscoded($this->podcast)));}}现在,进入最后一个方法。释放(延迟的)队列作业这可能是traittraits最有用的方法,因为它可以让你在未来进一步推动这个队列作业。这个方法用于queuejobratelimiting.除了ratelimiting,你还可以希望在不久的将来使用它,同时避免pre-emptivefailure.在最后一个例子中,我们将延迟转码以备后用:,我们将延迟转码5分钟,直到负载减少。podcast=$podcast;}/***执行队列作业。**@param\Transcoder\Transcoder$podcast*@returnvoid*/publicfunctionhandle(Transcoder$transcoder){//如果发布者已经被停用,请删除这个队列作业if($this->podcast->publisher->isDeactivated()){$this->delete();}//如果无法从存储中检索播客,我们将失败。如果($this->podcast->fileDoesntExists()){$this->fail(newPodcastUnretrievable($this->podcast));}//如果转码器使用率很高,我们将//t延迟转码5分钟进行编码。否则我们可能会有延误转码过程的危险//它会记录所有的转码子过程。如果($transcoder->getLoad()->isHigh()){$delay=60*5;$this->podcast->publisher->notify(newTranscoderHighUsage($this->podcast,$delay));$this->release($delay);}//告诉用户我们重试了多少次if($this->attempts()>1){$this->podcast->publisher->notify(newRetryingPodcastTranscode($this->podcast,$this->attempts());}$transcoded=$this->transcoder->setFile($event->podcast)->format('mp3')->bitrate(192)->start();//将转码后的播客与原始播客$this->podcast->transcode()->associate($transcoded);//通知播客的发布者他的播客已经准备好$this->publisher->notify(newPodcastTranscoded($this->podcast)));}}我们可以使用一些特殊的方法,例如,获取一些分配给转码器的槽,如果转码器槽已满,则延迟作业。这就是你在排队工作中所能做的。享受排队的乐趣。
