PHP Laravel 队列技巧:Fail、Retry 或者 Delay
当创建队列jobs、监听器或订阅服务器以推送到队列中时,您可能会开始认为,一旦分派,队列工作器决定如何处理您的逻辑就完全由您自己决定了。 嗯……并不是说你不能从作业内部与队列工作器交互,但是通常情况下,哪怕你做了,也是没必要的。 这个神奇的骚操作的出现是因为“InteractsWithQueue”这个trait。.当排队作业正在从队列中拉出,这个 [CallQueuedListener](https://github.com/laravel/framework/blob/5.8/src/Illuminate/Events/CallQueuedListener.php#L90-L104) 会检查它是否在使用 InteractsWithQueue trait,如果是的话,框架会将底层的“队列jobs”实例注入到内部。 这个 “任务” 实例类似于一个包装了真正的 Job 类的驱动,其中包含队列连接和尝试等信息。 背景 检查尝试次数 此方法旨在与其他方法一起使用 ...,类似 fail() 或者 release() (delay). 为了便于说明,我们将通知用户第几次重试: 每次我们尝试在空闲队列中转换(转换代码)时,我们都会通知用户我们正在第几次重试,让他可以选择取消将来的转换(转换代码)。 1 <?php 2 namespace AppJobs; 3 use AppPodcast; 4 use TranscoderTranscoder; 5 use IlluminateBusQueueable; 6 use IlluminateQueueSerializesModels; 7 use AppNotificationsPodcastTranscoded; 8 use IlluminateQueueInteractsWithQueue; 9 use IlluminateFoundationBusDispatchable; 10 use AppNotificationsRetyingPodcastTranscode; 11 class TranscodePodcast 12 { 13 use Dispatchable,InteractsWithQueue,Queueable, SerializesModels; 14 /** 15 * Transcoder Instance 16 * 17 * @var AppPodcast 18 */ 19 protected $podcast; 20 /** 21 * 创建一个新的转码podcast实例。 22 * 23 * @param AppPodcast $podcast 24 * @return void 25 */ 26 public function __construct(Podcast $podcast) 27 { 28 $this->podcast = $podcast; 29 } 30 /** 31 * 执行队列job. 32 * 33 * @param TranscoderTranscoder $podcast 34 * @return void 35 */ 36 public function handle(Transcoder $transcoder) 37 { 38 // 告诉用户我们第几次重试 39 if ($this->attempts() > 1) { 40 $this->podcast->publisher->notify(new RetryingPodcastTranscode($this->podcast,$this->attempts()); 41 } 42 $transcoded = $this->transcoder->setFile($event->podcast) 43 ->format('mp3') 44 ->bitrate(192) 45 ->start(); 46 47 48 // 将转码podcast与原始podcast关联 49 $this->podcast->transcode()->associate($transcoded); 50 51 // 通知podcast的发布者他的podcast已经准备好了 52 53 $this->publisher->notify(new PodcastTranscoded($this->podcast)); 54 } 55 }
就我个人而言,我喜欢在“Job作业”失败后再这样做,如果还有重试时间,告诉他我们稍后会重试当然,这个例子只是为了举例说明。 删除作业队列 Job 我们将在前面的示例中添加该代码: 1 <?php 2 namespace AppJobs; 3 use AppPodcast; 4 use TranscoderTranscoder; 5 use IlluminateBusQueueable; 6 use IlluminateQueueSerializesModels; 7 use AppNotificationsPodcastTranscoded; 8 use IlluminateQueueInteractsWithQueue; 9 use IlluminateFoundationBusDispatchable; 10 use AppNotificationsRetyingPodcastTranscode; 11 class TranscodePodcast 12 { 13 use Dispatchable, SerializesModels; 14 /** 15 * Transcoder Instance 16 * 17 * @var AppPodcast 18 */ 19 protected $podcast; 20 /** 21 * 创建一个新的转码podcast实例。 22 * 23 * @param AppPodcast $podcast 24 * @return void 25 */ 26 public function __construct(Podcast $podcast) 27 { 28 $this->podcast = $podcast; 29 } 30 /** 31 * 执行队列 job. 32 * 33 * @param TranscoderTranscoder $podcast 34 * @return void 35 */ 36 public function handle(Transcoder $transcoder) 37 { 38 // 如果发布服务器已被停用,请删除此队列job 39 if ($this->podcast->publisher->isDeactivated()) { 40 $this->delete(); 41 } 42 // 告诉用户我们第几次重试 43 if ($this->attempts() > 1) { 44 $this->podcast->publisher->notify(new RetryingPodcastTranscode($this->podcast,$this->attempts()); 45 } 46 $transcoded = $this->transcoder->setFile($event->podcast) 47 ->format('mp3') 48 ->bitrate(192) 49 ->start(); 50 51 // 将转码podcast与原始podcast关联 52 $this->podcast->transcode()->associate($transcoded); 53 54 // 通知podcast的发布者他的podcast已经准备好了 55 $this->publisher->notify(new PodcastTranscoded($this->podcast)); 56 } 57 }
失败的队列job 这使您在作业失败时可以更好地控制在任何情况下,也可以使用“failed()”方法,它允许你 失败后执行任何清洁操纵,比如通知用户或者删除一些东西。 在此示例中,如果由于任何原因(如 CDN 关闭时)无法从存储中检索podcast ,则作业将失败,并引发自定义异常。 1 <?php 2 namespace AppJobs; 3 use AppPodcast; 4 use TranscoderTranscoder; 5 use IlluminateBusQueueable; 6 use IlluminateQueueSerializesModels; 7 use AppExceptionsPodcastUnretrievable; 8 use AppNotificationsPodcastTranscoded; 9 use IlluminateQueueInteractsWithQueue; 10 use IlluminateFoundationBusDispatchable; 11 use AppNotificationsRetyingPodcastTranscode; 12 class TranscodePodcast 13 { 14 use Dispatchable, SerializesModels; 15 /** 16 * 转码器实例 17 * 18 * @var AppPodcast 19 */ 20 protected $podcast; 21 /** 22 * 创建一个新的转码Podcast实例。 23 * 24 * @param AppPodcast $podcast 25 * @return void 26 */ 27 public function __construct(Podcast $podcast) 28 { 29 $this->podcast = $podcast; 30 } 31 /** 32 * 执行队列 job. 33 * 34 * @param TranscoderTranscoder $podcast 35 * @return void 36 */ 37 public function handle(Transcoder $transcoder) 38 { 39 // 如果发布服务器已被停用,请删除此队列job 40 if ($this->podcast->publisher->isDeactivated()) { 41 $this->delete(); 42 } 43 //如果podcast不能从storage存储中检索,我们就会失败。 44 if ($this->podcast->fileDoesntExists()) { 45 $this->fail(new PodcastUnretrievable($this->podcast)); 46 } 47 // 告诉用户我们第几次重试 48 if ($this->attempts() > 1) { 49 $this->podcast->publisher->notify(new RetryingPodcastTranscode($this->podcast,$this->attempts()); 50 } 51 52 $transcoded = $this->transcoder->setFile($event->podcast) 53 ->format('mp3') 54 ->bitrate(192) 55 ->start(); 56 57 // 将转码podcast与原始podcast关联 58 $this->podcast->transcode()->associate($transcoded); 59 60 // 通知podcast的发布者他的podcast已经准备好了 61 $this->publisher->notify(new PodcastTranscoded($this->podcast)); 62 } 63 }
释放(延迟)队列job 除了速率限制之外,您还可以在某些不可用但希望在不久的将来使用它的情况下使用它同时,避免先发制人地失败。 在最后一个示例中,我们将延迟转码以备稍后使用:如果转码器正在大量使用,我们将延迟转码5分钟直到负载降低。 1 <?php 2 namespace AppJobs; 3 use AppPodcast; 4 use TranscoderTranscoder; 5 use IlluminateBusQueueable; 6 use IlluminateQueueSerializesModels; 7 use AppExceptionsPodcastUnretrievable; 8 use AppNotificationsPodcastTranscoded; 9 use IlluminateQueueInteractsWithQueue; 10 use AppNotificationsTranscoderHighUsage; 11 use IlluminateFoundationBusDispatchable; 12 use AppNotificationsRetyingPodcastTranscode; 13 class TranscodePodcast 14 { 15 use Dispatchable, SerializesModels; 16 /** 17 * Transcoder Instance 18 * 19 * @var AppPodcast 20 */ 21 protected $podcast; 22 /** 23 * 创建一个新的转码podcast实例。 24 * 25 * @param AppPodcast $podcast 26 * @return void 27 */ 28 public function __construct(Podcast $podcast) 29 { 30 $this->podcast = $podcast; 31 } 32 /** 33 * 执行队列job. 34 * 35 * @param TranscoderTranscoder $podcast 36 * @return void 37 */ 38 public function handle(Transcoder $transcoder) 39 { 40 // 如果发布服务器已被停用,请删除此队列job 41 if ($this->podcast->publisher->isDeactivated()) { 42 $this->delete(); 43 } 44 // 如果podcast不能从storage存储中检索,我们就会失败。 45 if ($this->podcast->fileDoesntExists()) { 46 $this->fail(new PodcastUnretrievable($this->podcast)); 47 } 48 49 // 如果转码器使用率很高,我们将 50 // t延迟转码5分钟. 否则我们可能会有拖延转码器进程的危险 51 // 它会把所有的转码子进程都记录下来。 52 if ($transcoder->getLoad()->isHigh()) { 53 $delay = 60 * 5; 54 $this->podcast->publisher->notify(new TranscoderHighUsage($this->podcast,$delay)); 55 $this->release($delay); 56 } 57 // 告诉用户我们第几次重试 58 if ($this->attempts() > 1) { 59 $this->podcast->publisher->notify(new RetryingPodcastTranscode($this->podcast,$this->attempts()); 60 } 61 62 $transcoded = $this->transcoder->setFile($event->podcast) 63 ->format('mp3') 64 ->bitrate(192) 65 ->start(); 66 67 // 将转码podcast与原始podcast关联 68 $this->podcast->transcode()->associate($transcoded); 69 70 // 通知podcast的发布者他的podcast已经准备好了 71 $this->publisher->notify(new PodcastTranscoded($this->podcast)); 72 } 73 }
(编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |