【发布时间】: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);) 没有任何反应,也许记录会是已删除,但已触发通知...
-
这并不让我感到惊讶 - 作业详细信息已被获取并即将运行。删除后您可能会抛出异常 - 应该停止工作人员,然后在下次检查数据库时该作业消失。