Laravel Forge: Preventing Queue Contamination In Shared Redis Queues

Laravel queued jobs are one of the many things that make developing with Laravel a breeze. If you use Forge, things get even easier as you get a pretty UI to configure your queues.

This works quite well if you have only one instance of an app running on the server. Most applications run this way, with a dedicated instance powering a single staging or a production environment.

In such situations, the queue names are of no great consequence as the production server will contain only production data, staging servers contain only staging data and so on and so forth.

The trouble starts when you have a shared instance that hosts both production and staging. In such a scenario, if you add jobs to the ‘default’ queue, it may wind up causing two different problems.

  1. The model ID that you are working on may not exist if the worker that processes the job is from the wrong instance. This will cause the job to fail.
  2. The model ID may overlap with an existing model ID on the wrong instance and you may wind up performing actions on the wrong model. This problem is far more dangerous.

Laravel Forge has an ‘environment’ option in the worker configuration screen, but I have not been able to figure out what that actually does. Additionally, I feel safer having different dedicated queues for each environment than handle the context within the worker.

The easy workaround is to have the queue names set as environment variables and then set up the workers with the correct queue names, depending on the environment.

When you dispatch the job, you will call the queue name from the environment value:

CreateJobsFromMasterQueue::dispatch($this)->onQueue(env('APP_QUEUE_JOBSMASTER'));

The queue name is defined in the .env file. This allows us to have different queue names for different environments.

APP_QUEUE_JOBSMASTER=localJobsMaster

You do have to keep in mind that libraries may choose to fallback to the ‘default’ queue. Spatie’s Laravel Medialibrary does this. In such scenarios, you have to publish the configuration file to override the default and provide the correct queue name for it.

Update: May 16, 2019

To work around the problem of the default queue being used by most code. You have to edit the config/queue.php file.

'queue' => env('APP_QUEUE_DEFAULT', 'default')

The above change allows for default queues to be customized.

Never mind.