7
Trait method dispatch has not been applied, because there are collisions with other trait methods on 

I'm always getting the above error, now I want to use both Dispatchable and DispatchJobs in a job, how could I do that? Any help or guidance will be highly appreciated. Looked for few solutions on Laracasts but none worked.

Siddharth
  • 1,649
  • 4
  • 22
  • 47
  • 4
    Be careful when dispatching a job within another job! For example: JOB A and JOB B. When dispatching JOB B within JOB A, whenever something fails within JOB A after JOB B was dispatched, JOB B will be dispatched again when JOB A is being retried! – v1nk0 Dec 18 '18 at 11:20

4 Answers4

6

Use the global dispatch() helper and that will work to dispatch another job inside the job. So we don't need to add DispatchesJobs at all (which removes the conflict with Dispatchable) and you can just use the helper dispatch() instead and it works

Siddharth
  • 1,649
  • 4
  • 22
  • 47
4

Jobs don't typically dispatch other Jobs, so start by removing the DispatchJobs trait. What you can do is listen for job events.

When a Job completes, it fires the after event. Listen for this event and then dispatch() the next Job within the listener:

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Queue::after(function (JobProcessed $event) {
        // determine the job type from $event->job
        // then dispatch the next job based on your logic

        // check the job type
        if ($event->job instanceof MyJob) {
            // get the job payload to pass to next job
            $data = $event->job->payload

            dispatch(new NextJob($data));
            // or use the static method
            NextJob::dispatch($data);
        }
    });
}
  • Hi @btl, thank you for the reply, I still need your little guidance, now From JOB A, I need to pass some data which is going to be used in JOB B, how could I do that with the after event? And how would I recognise the particular job. I want to fire the event only when JOB A ends. Thank you :) – Siddharth Feb 17 '18 at 07:20
  • thank you so much, but I also found a better solution :), just using global `dispatch();` it doesn't make any conflicts and it works smoothly. – Siddharth Feb 17 '18 at 07:26
  • I've answered my own question, you may take a look :) @btl – Siddharth Feb 17 '18 at 07:30
  • @Siddharth do you have to explicitly set ```\dispatch()``` or simply ```dispatch()``` to make a global call to it? – Ulterior Oct 11 '18 at 09:39
  • 1
    @Ulterior simply dispatch() – Siddharth Oct 11 '18 at 14:10
4

This worked for me

inside the BbtvAdvJob I dispatch again.

 dispatch(new BbtvAdvJob())->delay(3);

make sure that you recall php artisan queue:work when you change the code of the Job.

danronmoon
  • 3,814
  • 5
  • 34
  • 56
Mansour Alnasser
  • 4,446
  • 5
  • 40
  • 51
1

From Laravel >=5.3

If your job class is MyAnotherJob, try dispatching

MyAnotherJob::dispatch()

Every Job class has a static dispatch function. You can use that.

Rafik Farhad
  • 1,182
  • 2
  • 12
  • 21