【问题标题】:Laravel - How to delete a job (Notification)Laravel - 如何删除作业(通知)
【发布时间】:2017-07-27 14:22:25
【问题描述】:

在我的应用程序中,用户可以安排消息(如提醒),时间到了,应用程序上会出现一个弹出窗口。为此,我创建了一个通知,并通过 Websocket 发送它。

现在,假设用户插入了错误的日期(或者简单地说,想要更改提醒日期),我需要在执行之前访问 JOB。

我确实尝试了很多解决方案,但没有奏效......

我的通知类是:

class RemindNote extends Notification implements ShouldQueue, ShouldBroadcast
{
    use Queueable;
    use InteractsWithQueue;
}

RemindNote 上尝试过的处理方法:

public function handle($event) {
   $this->delete();
}

激活php artisan queue:work,当我安排通知时,handle 方法永远不会被调用。

试过 Queue::before 开启 AppServiceProvider

这个方法被调用,但是如果我调用$event->job->delete(),通知总是被触发 - 作业被删除。但是,例如,如果我打电话给$event->job->release(),工作会重新安排

那么,有一种方法可以访问 JOB 有效负载并在执行之前将其删除?

编辑

\Queue::before(function(JobProcessing $event) {
    \Log::debug($event->job->isDeleted());
    $event->job->delete();
});

有了这个,当作业被处理时,我会在 laravel.log 中看到这个:

[2017-07-27 16:44:35] stage.DEBUG:   
[2017-07-27 16:44:36] stage.DEBUG:  

而且,通知总是被触发。好像delete() on before hook没有效果。

编辑 这是 Queue::before 上记录的有效负载(方法 $event->job->payload()):

[2017-07-27 15:00:13] stage.INFO: array (
  'job' => 'Illuminate\\Queue\\CallQueuedHandler@call',
  'data' => 
  array (
    'commandName' => 'Illuminate\\Notifications\\SendQueuedNotifications',
    'command' => 'O:48:"Illuminate\\Notifications\\SendQueuedNotifications":6:{s:14:"' . "\0" . '*' . "\0" . 'notifiables";O:45:"Illuminate\\Contracts\\Database\\ModelIdentifier":2:{s:5:"class";s:26:"App\\Repositories\\User\\User";s:2:"id";a:1:{i:0;i:29;}}s:15:"' . "\0" . '*' . "\0" . 'notification";O:28:"App\\Notifications\\RemindNote":7:{s:4:"body";s:3:"ddf";s:4:"user";O:45:"Illuminate\\Contracts\\Database\\ModelIdentifier":2:{s:5:"class";s:26:"App\\Repositories\\User\\User";s:2:"id";i:29;}s:2:"id";s:36:"e160802c-e9e5-4d2c-a1e1-d63cbdceb54c";s:10:"connection";N;s:5:"queue";N;s:5:"delay";O:13:"Carbon\\Carbon":3:{s:4:"date";s:26:"2017-07-27 14:31:00.000000";s:13:"timezone_type";i:3;s:8:"timezone";s:11:"Europe/Rome";}s:6:"' . "\0" . '*' . "\0" . 'job";N;}s:11:"' . "\0" . '*' . "\0" . 'channels";a:1:{i:0;s:9:"broadcast";}s:10:"connection";N;s:5:"queue";N;s:5:"delay";r:14;}',
  ),
)  
[2017-07-27 15:00:13] stage.INFO: array (
  'job' => 'Illuminate\\Broadcasting\\BroadcastEvent',
  'data' => 
  array (
    'event' => 'O:60:"Illuminate\\Notifications\\Events\\BroadcastNotificationCreated":6:{s:10:"notifiable";O:45:"Illuminate\\Contracts\\Database\\ModelIdentifier":2:{s:5:"class";s:26:"App\\Repositories\\User\\User";s:2:"id";i:29;}s:12:"notification";O:28:"App\\Notifications\\RemindNote":7:{s:4:"body";s:3:"ddf";s:4:"user";O:45:"Illuminate\\Contracts\\Database\\ModelIdentifier":2:{s:5:"class";s:26:"App\\Repositories\\User\\User";s:2:"id";i:29;}s:2:"id";s:36:"e160802c-e9e5-4d2c-a1e1-d63cbdceb54c";s:10:"connection";N;s:5:"queue";N;s:5:"delay";O:13:"Carbon\\Carbon":3:{s:4:"date";s:26:"2017-07-27 14:31:00.000000";s:13:"timezone_type";i:3;s:8:"timezone";s:11:"Europe/Rome";}s:6:"' . "\0" . '*' . "\0" . 'job";N;}s:4:"data";a:1:{s:4:"body";s:3:"ddf";}s:10:"connection";N;s:5:"queue";N;s:5:"delay";N;}',
  ),
)  

【问题讨论】:

  • 您必须将其从队列中删除。您如何这样做取决于您使用的队列引擎。
  • 我正在使用数据库队列
  • 你可以在数据库中找到记录并删除它。
  • If in Queue:before i access to job id and then delete (\DB::delete('delete from jobs where id = ' . $id);) 没有任何反应,也许记录会是已删除,但已触发通知...
  • 这并不让我感到惊讶 - 作业详细信息已被获取并即将运行。删除后您可能会抛出异常 - 应该停止工作人员,然后在下次检查数据库时该作业消失。

标签: php laravel laravel-5


【解决方案1】:

您可以对Queue::before 事件运行回调。

在数据库中将提醒标记为已删除,然后在您的Queue::before 回调中检查作业是否已被删除,如果已删除,则在处理之前将作业从队列中删除。

查看文档中的工作事件:https://laravel.com/docs/5.4/queues#job-events

[编辑] 刚刚看到你的编辑。如果您使用job->delete(),则不应处理该作业。这可能是延迟作业的错误吗?

另外,当您对班级进行更改时,您是否停止并重新启动了队列侦听器?我掉进了这个陷阱。

【讨论】:

  • 我试图将 $job->delete() 放在 Queue::before 中,但作业总是被执行。现在,我用 isDeleted() 放置了一个日志,然后我调用 delete(),日志显示一个空行。查看我的编辑
  • @Mistre83 您是否尝试将整个事件转储到日志中以查看其中的内容?
  • 是的,当工作人员处理作业时,如果我记录 payload(),我可以看到所有信息.. 一个与 CallQueueHandler 相关,另一个与 BroadcastEvent 相关...但没有帮助..我更新了线程。
猜你喜欢
  • 2014-12-08
  • 1970-01-01
  • 2021-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多