Queues Flashcards
(56 cards)
In order to use the database queue driver, you will need a database table to hold the jobs. Typically, this is included in Laravel’s default 0001_01_01_000002_create_jobs_table.php database migration; however, if your application does not contain this migration, which Artisan command do you need to run to change that?
php artisan make:queue-table
php artisan migrate
By default, where does your application store all queueable jobs?
app/Jobs
Which method does a job class contain and when does it get invoked?
Normally a job class only contains a handle method that is invoked when the job is processed by the queue.
How can you stop multiple instances of a specific job from entering the queue, only allowing one of them to be in the queue at a time?
You may do that by implementing the ShouldBeUnique interface on your job class. This interface does not require you to define any additional methods on your class. Unique jobs require a cache driver that supports locks. Currently, the memcached, redis, dynamodb, database, file and array cache drivers support atomic locks. In addition, unique job constraints do not apply to jobs within batches.
By default, unique jobs are “unlocked” after a job completes processing or fails all of its retry attempts. However, there may be situations where you would like your job to unlock immediately before it is processed. How can you make that happen?
To accomplish this, your job should implement the ShouldBeUniqueUntilProcessing contract instead of the ShouldBeUnique contract. Also, just like with the ShouldBeUnique contract, the ShouldBeUniqueUntilProcessing contract does not require you to implement any methods.
Behind the scenes, when a ShouldBeUnique job is dispatched, Laravel attempts to acquire a lock with the uniqueId key. What happens, if the lock is not acquired?
The job is not dispatched
How can you encrypt your jobs?
Laravel allows you to ensure the privacy and integrity of a job’s data by encrypting it using the ShouldBeEncrypted interface, which you can simply add to your job class and once this interface has been added, Laravel will automatically encrypt your job before pushing it onto a queue
Once you have written your job class, how can you dispatch it?
By using the dispatch method on the job itself.
ExampleJob::dispatch($argument);
The arguments passed to the dispatch method will be given to the job’s constructor.
If you would like to conditionally dispatch a job, you may use the dispatchIf($condition, $attributes)
or dispatchUnless(same arguments as dispatchIf)
methods
How can you specify that a job should not be available for processing by a queue worker immediately?
Use the delay method
ExampleJob::dispatch($arguments)->delay(now()->addMinutes(10));
In this example the Job would not be processed within the first 10 minutes of it being dispatched
How can you make the dispatching of the job wait until the HTTP response is sent to the user’s browser allowing the user to keep using the application even though a queued job is still executing?
::dispatchAfterResponse()
This should typically only be used for jobs that take about a second, such as sending an email. Since they are processed within the current HTTP request, jobs dispatched in this fashion do not require a queue worker to be running in order for them to be processed.
How can you dispatch a job immediately (synchronously) and what does that do?
If you would like to dispatch a job immediately (synchronously), you may use the dispatchSync method. When using this method, the job will not be queued and will be executed immediately within the current process. The dispatchSync method takes arguments just like the normal dispatch method.
While it is perfectly fine to dispatch jobs within database transactions, which major issue could occur by doing that?
When dispatching a job without a transaction, it is possible that the job will be processed by a worker before the parent transaction has committed. When this happens, any updates you have made to the models or database records during the database transaction(s) may not yet be reflected in the database. In addition, any models or database records created within the transaction(s) may not exist in the database.
How can you stop a job from being finished before a parent transaction has been committed?
You may set the after_commit connection option in your queue connection’s configuration array:
'redis' => [ 'driver' => 'redis', // ... 'after_commit' => true, ],
When the after_commit option is true, you may dispatch jobs within database transactions; however, Laravel will wait until the open parent dtabase transactions have been committed before actually dispatching the job. Of course, if no database transactions are currently open, the job will be dispatched immediately. If a transaction is rolled back due to an exception that occurs during the transaction, the jobs that were dispatched during that transaction will be discarded.
What is a job chain and how can you set it up?
Chaining jobs allows you to specify a list of queued jobs that should be run in sequence after the primary job has executed successfully. If one job in the sequence fails, the rest of the jobs will not be run. To execute a queued job chain, you may use the chain method provided by the Bus facade. Laravel’s command bus is a lower level component that queued job dispatching is build on top of:
Bus::chain([ new ProcessSong, new OptimizeSong, new ReleaseSong, ])->dispatch();
How can you append or prepend something to a jobs chain and what exactly does that do?
You can simply use the prependToChain or appendToChain methods from within another job in that chain like this:
$this->prependToChain(new ExampleJob); $this->appendToChain(new ExampleJob);
Prepending will make the newly added job run immediately after the current job and appending will add it to the end of the chain.
How can you handle a job queue failing?
You can simply invoke the catch method on the chain to receive the Throwable instance that caused the job failure. Since chain callbacks are serialized and executed at a later time by the Laravel queue, you should not use the $this variable within chain callbacks and instead apply the catch method right when creating the chain using the chain method of the Bus facade.
If your application interacts with multiple queue connections, how can you specify which connection to push a job to?
You may specify the connection using the onConnection method:ExampleJob::dispatch(arguments)->onConnection('sqs');
Which variable do you need to set to specify the amount of times that a job will be attempted for?
While starting the job using Artisan:php artisan queue:work --tries=3
or within the job class:public $tries = 5;
This would try to do the job 5 times before failing.
If you want your job to retry indefinitely, how do you need to modify your job class?
public $tries = 0;
Setting the amount of tries to 0 will make it retry indefinitely
Modify a job class so that it retries it’s job for 10 minutes before failing!
public function retryUntil(): DateTime { return now()->addMinutes(10); }
What is the default timeout value for a job in Laravel?
60 seconds
How can you set a custom timeout value?
Either when running the job using Artisan:php artisan queue:work --timeout=120
Or directly in the job’s class:public $timeout = 120;
How can you indicate that a job should be marked as failed on timeout?
public $failOnTimeout = true;
What does Laravel do with a job that failed but still has x amounts of tries left?
The failed job gets put back into the queue to be picked up again by a worker and Laravel will only stop putting it back into the queue if your job runs out of tries or the given time span runs out