Search code examples
phplaravelqueuejobslaravel-5.8

Laravel Job executed immediately in browser instead of running in a background queue


I'm new to Laravel, and tried to create my first background task.

Used docs: https://laravel.com/docs/master/queues

Job: (ProcessDatabaseImport.php)

<?php

namespace App\Jobs;

use App\Contact;
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\Log;
use Illuminate\Support\Facades\File;

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

    protected $file;

    /**
     * Create a new job instance.
     *
     * @param String $filePath
     * @return void
     */
    public function __construct($filePath)
    {
        // init File object "database/data/contacts.json"
        $this->file = base_path($filePath);
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
       Log::info('Hello world! file: '.$this->file);
    }

    /**
     * Determine the time at which the job should timeout.
     *
     * @return \DateTime
     */
    public function retryUntil()
    {
        return now()->addSeconds(30);
    }
}
?>

JobController.php:

<?php

namespace App\Http\Controllers;

use App\Jobs\ProcessDatabaseImport;
use Carbon\Carbon;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Support\Facades\Queue;

class JobController extends Controller
{
    /**
     * Handle Queue Process
     */
    public function processQueue()
    {
        ProcessDatabaseImport::dispatch('database/data/contacts.json')->delay(now()->addMinutes(2));

        return view('home');
    }
}

Jobs table is created, php artisan queue:work is running.

Now, when i go to the controller action in my browser, the code in "handle()" is exectuted twice, directly:

Log:

[2019-07-14 13:39:17] local.INFO: Hello world! file: B:\hellodialog\sollicitatieopdracht\database/data/contacts.json  
[2019-07-14 13:39:18] local.INFO: Hello world! file: B:\hellodialog\sollicitatieopdracht\database/data/contacts.json  

The database table for jobs is always empty.

In my .env file:

DB_CONNECTION=mysql
QUEUE_CONNECTION=database

queue.php config file:

return [


    'default' => env('QUEUE_CONNECTION', 'database'),

    'connections' => [

        'sync' => [
            'driver' => 'sync',
        ],

        'database' => [
            'driver' => 'database',
            'table' => 'jobs',
            'queue' => 'default',
            'retry_after' => 90,
        ],

        'beanstalkd' => [
            'driver' => 'beanstalkd',
            'host' => 'localhost',
            'queue' => 'default',
            'retry_after' => 90,
            'block_for' => 0,
        ],

        'sqs' => [
            'driver' => 'sqs',
            'key' => env('AWS_ACCESS_KEY_ID'),
            'secret' => env('AWS_SECRET_ACCESS_KEY'),
            'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
            'queue' => env('SQS_QUEUE', 'your-queue-name'),
            'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
        ],

        'redis' => [
            'driver' => 'redis',
            'connection' => 'default',
            'queue' => env('REDIS_QUEUE', 'default'),
            'retry_after' => 90,
            'block_for' => null,
        ],

    ],

    'failed' => [
        'database' => env('DB_CONNECTION', 'mysql'),
        'table' => 'failed_jobs',
    ],

Is something missing?

Update: The job is added to the queue when I changed the default in queue.php

The job is now added twice to the database. I run this script by visiting the URL in my browser.


Solution

  • Sounds like you have two questions.

    Running immediately in the browser

    As for running immediately, this could happen if Laravel is still using the default sync driver. Check your /config/queue.php file and make sure the env() property is being used. Sync is the default fallback if no queue driver is set in your .env file, but you could also change this if you want.

    'default' => env('QUEUE_CONNECTION', 'sync'),
    

    If everything looks okay, try running php artisan config:clear to empty the config cache. It's possible that the default sync driver is still cached.

    Alternatively, you can try explicitly defining the connection you wish to use.

    ProcessDatabaseImport::dispatch('database/data/contacts.json')
        ->onConnection('database')
        ->delay(now()->addMinutes(2));
    

    Running twice

    I'm not sure about this, but what happens if you remove the retryUntil() method from the Job?

    Also, I found a similar issue in another thread, but I don't know if it's related.
    Queued Laravel queued job runs twice after upgrading to Laravel 5.4

    If this doesn't help, we might need more information about how you are initiating the job. Are you simply visiting a URL, or is it possible that the mechanism to call this route could be running twice (e.g., via Ajax)?

    And you might add the applicable /config/queue.php configuration to your question, as there is some indication from the thread mentioned above that your retry and timeout times may come into play.