Hello,
I have an event subscriber that works well if I don't use ShouldQueue, but it fails when using it.
This is the code:
<?php
namespace App\Listeners;
use App\Events\OrderTaskUpdated;
use App\OrderTask;
use App\Service\MessagingService;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Events\Dispatcher as Dispatcher;
class NotificationListener implements ShouldQueue
{
private $messagingService;
/**
* Create the event listener.
* @param MessagingService $messagingService
*/
public function __construct(MessagingService $messagingService)
{
$this->messagingService = $messagingService;
}
/**
* Handle OrderTaskUpdated event
*
* @param OrderTaskUpdated $event
* @return void
*/
public function onOrderTaskUpdated(OrderTaskUpdated $event)
{
// Do things...
}
/**
* Register the listeners for the subscriber.
*
* @param Dispatcher $events
*/
public function subscribe(Dispatcher $events)
{
$events->listen(
OrderTaskUpdated::class,
'App\Listeners\NotificationListener@onOrderTaskUpdated'
);
}
}
The error generated is:
local.ERROR: exception 'ErrorException' with message 'call_user_func_array() expects parameter 1 to be a valid callback, class 'App\Listeners\NotificationListener' does not have a method 'onOrderTaskStatusUpdated'' in /vendor/laravel/framework/src/Illuminate/Events/CallQueuedHandler.php:43
I guess that is something related with the subscriber loading when running the job, but I don't know how to fix it. Am I doing something wrong?
Thanks!
We do not support custom methods in that way. You must just provide the class name, and a handle method.
Hmm, actually, we should support this, but this doesn't look like a Laravel bug. It looks like you've registered another listener somewhere else and forgotten about it, or forgotten to restart the queue worker to load the new mappings.
I already have tried to restart the queue workers several times, and I also have tried to clear the Laravel cache and dump the composer autoload, but it didn't solve the problem.
I don't have other listeners, and I have searched in the vendors to be sure that there is no other listener with the same name interfering with mine.
This is the code of the OrderTaskUpdated event:
namespace App\Events;
use App\OrderTask;
use Illuminate\Queue\SerializesModels;
class OrderTaskUpdated extends Event
{
use SerializesModels;
public $task;
/**
* Create a new event instance.
*
* @param OrderTask $task
*/
public function __construct(OrderTask $task)
{
$this->task = $task;
}
}
And that event is fired in the AppServiceProvider boot method using the eloquent model updated event like this:
public function boot()
{
OrderTask::updated(function ($task) {
Event::fire(new OrderTaskUpdated($task));
});
}
But my question is, why is this working when I don't use the ShoudQueue but it fails when I use it?
Maybe is something related with the DI or with the way the event subscriber is loaded in the worker?
I can't replicate this?
Give me a few minutes. I will create a new project and try to replicate the error.
Sorry Graham, after failing to replicate the problem in a new project, I have finally found the problem, and as usual it was a silly thing. There was a worker running in the background as daemon that must not be there, and it was the one consuming all the jobs and generating all the errors.
Sorry again for wasting your time and thanks a lot for your help.
I had exactly the same issue. I am developing on Windows so I didn't know exactly how to find the running daemon, so I had to reactivate the individual listeners and let the jobs fail. Then I stopped the queue, added my subscriber back and deleted the individual listeners and all was happy. Seems like there should be a better process for that though.
Most helpful comment
Sorry Graham, after failing to replicate the problem in a new project, I have finally found the problem, and as usual it was a silly thing. There was a worker running in the background as daemon that must not be there, and it was the one consuming all the jobs and generating all the errors.
Sorry again for wasting your time and thanks a lot for your help.