12

I'm trying to get the job ID inside my jobs. I try $this->job->getJobId() but it returns an empty string.

<?php

namespace App\Jobs\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\Auth;

class SendNotification implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct($notification, $fireShutdown)
    {
        $this->notification = $notification;
        $this->fireShutdown = $fireShutdown;
    }

    public function handle()
    {
        dd($this->job->getJobId());

       // Some Code
    }
}
Karl Hill
  • 12,937
  • 5
  • 58
  • 95
Kenneth
  • 2,813
  • 3
  • 22
  • 46

3 Answers3

10

The following will allow you to get the job id. Try to copy the code below and dispatch it with a simple route.

class TestJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        echo $this->job->getJobId();
    }
}

And the following route to test it.

Route::get('/trigger', function () {
    dd(dispatch(new \App\Jobs\TestJob()));
});

In your terminal, you should now see the following, with the id of your given job.

Terminal returning the job id

If your queue listener isn't running you can start it by typing the following in the terminal

php artisan queue:work redis --tries=3

If you are trying to return the id to your controller/route, you cannot do this with an async/queued job due to the nature of it being async/queued.

Nicklas Kevin Frank
  • 6,079
  • 4
  • 38
  • 63
  • Which queue driver are you using? And could you try dispatching 10+ of the TestJob in the trigger? – Nicklas Kevin Frank May 03 '19 at 06:32
  • It's the same to all jobs. It return 0 to all jobs. – Kenneth May 03 '19 at 06:45
  • Remember to restart the queue listener after making changes to the code. – Nicklas Kevin Frank May 03 '19 at 06:48
  • @Kenneth There is nothing wrong with the above code. You can copy paste this into a new Laravel repository, and it will correctly return the job id. – Nicklas Kevin Frank May 03 '19 at 10:00
  • I already tried your code. But It returns a `PendingDispatch` object. empty objects. – Kenneth May 03 '19 at 10:07
  • @Kenneth Yes, but in the terminal that you have running with a queue listener, you should see the id printed. You cannot get an async job to return the id to your controller/route. – Nicklas Kevin Frank May 03 '19 at 10:10
  • @Kenneth Which specific version of Laravel are you using? I am running version `5.8.15` and it is working fine. Let me know, and I can try to test it using the same specific version. – Nicklas Kevin Frank May 03 '19 at 11:32
  • @NicklasKevinFrank I've tried your code and indeed works, but it's nonsense to output the job ID to console.I'm trying to return it from the Job class to the controller so the user can keep track of the job id on queue. I *must* implement a way to kill the process itself by its id. It's known the job has an id on database and it is PK, so I believe there should be a way to retrieve it at creation time and return it to the dispatcher method (in the controller).-using laravel 5.8- What do you think? – fernandojmartin Jul 03 '19 at 21:30
  • 2
    @NicklasKevinFrank @kenneth Jeez!! Just found [this answer](https://stackoverflow.com/questions/46785656/in-laravel-5-5-how-to-get-the-job-id-after-we-dispatch-a-job-to-the-job-queue), tried it and **it worked**!! This is my line: `dump(app(\Illuminate\Contracts\Bus\Dispatcher::class)->dispatch(new TestQueue($source)));` In browser: #14 << The real database ID – fernandojmartin Jul 03 '19 at 21:38
  • @fernandojmartin This answer should work too? The example route `/trigger` will show the id in the browser too. – Nicklas Kevin Frank Jul 09 '19 at 15:10
  • @NicklasKevinFrank I'm not sure. I haven't a `/trigger` route. Maybe it's some kind of magic? See my answer below (not comment). Anyway, I have it working now. Thank you. – fernandojmartin Jul 10 '19 at 18:53
1

Just found this answer and it seems to be still compatible on 5.8!

Routes file

Route::get('/queue/{count?}', function($count = 10) {
    $source = new stdClass;
    $source->count = $count;

    // dump(TestQueue::dispatch($source)->delay(now()->addSeconds(10)));
    dump(app(\Illuminate\Contracts\Bus\Dispatcher::class)->dispatch(new TestQueue($source)));

    return "Queued! Will loop {$source->count} times.";
});

TestQueue class file

class TestQueue implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $source;

    public function __construct(\stdClass $source)
    {
        $this->source = $source;
    }

    public function handle()
    {
        for ($i = 1; $i <= $this->source->count; $i++) {
            logger("Loop #{$i} of {$this->source->count}");
            sleep(1);
        }
    }
}

In browser

Real database ID column!


WARNING: It looks can't implement delays. It just fires out whenever you call it.

    dump(
        app(\Illuminate\Contracts\Bus\Dispatcher::class)
            ->dispatch(new TestQueue($source))
            ->delay(now()->addSeconds(10))
    );

ERROR: Call to a member function delay() on integer {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalThrowableError(code: 0): Call to a member function delay() on integer at ...web.php:50)"}

fernandojmartin
  • 178
  • 1
  • 14
0

This worked for me and I got the ID value.
$jobID = SendNotification::dispatch();
$job_id = collect(collect($jobID)->first())->first();
dd($job_id); // will result in the $job_id

AMIT PATEL
  • 31
  • 1