1
Q

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?

A

php artisan make:queue-table
php artisan migrate

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

By default, where does your application store all queueable jobs?

A

app/Jobs

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Which method does a job class contain and when does it get invoked?

A

Normally a job class only contains a handle method that is invoked when the job is processed by the queue.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

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?

A

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.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

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?

A

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.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

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?

A

The job is not dispatched

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

How can you encrypt your jobs?

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Once you have written your job class, how can you dispatch it?

A

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 well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

How can you specify that a job should not be available for processing by a queue worker immediately?

A

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 well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

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?

A

::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 well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

How can you dispatch a job immediately (synchronously) and what does that do?

A

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.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

While it is perfectly fine to dispatch jobs within database transactions, which major issue could occur by doing that?

A

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 well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

How can you stop a job from being finished before a parent transaction has been committed?

A

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.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

What is a job chain and how can you set it up?

A

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 well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

How can you append or prepend something to a jobs chain and what exactly does that do?

A

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 well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

How can you handle a job queue failing?

A

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.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

If your application interacts with multiple queue connections, how can you specify which connection to push a job to?

A

You may specify the connection using the onConnection method:
ExampleJob::dispatch(arguments)->onConnection('sqs');

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

Which variable do you need to set to specify the amount of times that a job will be attempted for?

A

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.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

If you want your job to retry indefinitely, how do you need to modify your job class?

A

public $tries = 0;

Setting the amount of tries to 0 will make it retry indefinitely

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

Modify a job class so that it retries it’s job for 10 minutes before failing!

A
public function retryUntil(): DateTime
{
    return now()->addMinutes(10);
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

What is the default timeout value for a job in Laravel?

A

60 seconds

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

How can you set a custom timeout value?

A

Either when running the job using Artisan:
php artisan queue:work --timeout=120

Or directly in the job’s class:
public $timeout = 120;

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

How can you indicate that a job should be marked as failed on timeout?

A

public $failOnTimeout = true;

24
Q

What does Laravel do with a job that failed but still has x amounts of tries left?

A

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

25
Which method do you need to call on the job class to put it into the queue again?
`$this->release();` If you wish for the job to not potentially be processed immediately you can add a delay: `$this->release(now()->addSeconds(10));`
26
Manually mark a job as failed!
`$this->fail();` You may also pass an exception that was caught: `$this->fail($exception);` or you may pass a string error message which will be converted to an exception: `$this->fail('Something went wrong.');`
27
Start a queue worker using Artisan!
`php artisan queue:work` This worker would run until it is either manually stopped or until the terminal window is closed
28
What type of problem might arise when applying changes to the code while the queue workers are still running?
Queue workers are long-lived processes and store the booted application state in memory. As a result, they will not notice changes in your code base after they have been started leading to a multitude of potential issues connected to the changes to the original state of the code not being applied yet. So, during your deployment process, be sure to restart your queue workers.
29
How can you start a worker that doesn't manually need to be restarted when you want to reload your updated code or reset the application state?
`php artisan queue:listen` This command is significantly less efficient than the queue:work command
30
What do you need to do to assign multiple workers to a queue and process jobs concurrently?
You should simply start multiple queue:work processes. This can either be done locally via multiple tabs in your terminal or in production using your process manager's configuration settings.
31
Given an application that processes emails in an "emails" queue on a "redis" queue connection, how can you start a queue worker that specifically only processes that queue in that connection?
php artisan queue:work redis --queue=emails
32
Start a queue worker that only processes a single job from the queue before stopping!
php artisan queue:work --once
33
How can you make a queue worker process a set amount of jobs before stopping?
php artisan queue:work --max-jobs=1000 This worker would process 1000 jobs from the queue and then stop
34
Set up a queue worker that will participate in working on the queue as long as jobs exist within it and then exits when the queue is empty!
php artisan queue:work --stop-when-empty
35
How can you create a queue worker that stops running after a set amount of time?
php artisan queue:work --max-time=3600 The time is in seconds, so a max time of 3600 means that the worker will run for an hour. This is really useful for when there is a sudden burst of traffic
36
Create a worker that will process jobs as long as there are jobs in the queue and waits for a set amount of seconds if the queue is empty before exiting!
php artisan queue:work --sleep=3
37
When having your application in maintenance mode, no queued jobs will be handled. The workers will only resume their work once the application is out of maintenance mode. How can you make a worker, that will process jobs even if maintenance mode is enabled?
By using the --force option: php artisan queue:work --force Obviously this can be combined with other options and can be useful to create workers that finish up everything that is still in the queue when going into maintenance mode
38
How can you mark a job as a high priority job before queuing it?
When dispatching the job you can add an onQueue that sets the priority. What it basically does is that you have two separate queues and if anything is in the high priority queue it gets processed before the workers even check if and what might be on the low priority queue. `dispatch((new Job)->onQueue('high'));`
39
How can you start a worker that verifies that all of the high priority jobs are finished before starting to work on a low priority job?
php artisan queue:work --queue=high,low This worker will take care of all high priority jobs before working on any low priority jobs
40
Since queue workers are long-lived processes, they will not notice changes to your code without being restarted. So, the simplest way to deploy an application using queue workers is to restart the workers during your deployment process. How can you do that?
php artisan queue:restart This command will instruct all queue workers to gracefully exit after they finish processing their current job so that no existing jobs are lost. Since the queue workers will exit when the queue:restart command is executed, you should be running a process manager such as Supervisor to automatically restart the queue workers. The queue uses the cache to store restart signals, so you should verify that a cache driver is properly configured for your application before using this feature.
41
Within your config/queue.php configuration file, each queue connection defines a retry_after option. What does this option specify?
This option specifies how many seconds the queue connection should wait before retrying a job that is being processed. For example, if the value of `retry_after` is set to 90, the job will be released back onto the queue if it has been processing for 90 seconds without being released or deleted. Typically, you should set the `retry_after` value to the maximum number of seconds your jobs should reasonably take to complete processing.
42
Why should your --timeout value always be below your retry_after configuration value?
Having the `--timeout value` below the `retry_after` config value will ensure that a worker processing a frozen job is always terminated before the job is retried. If your `--timeout option` is longer than your `retry_after` config value, your jobs may be processed twice.
43
Why should you always use a process monitor like Supervisor for your queue workers?
In production, you need a way to keep your queue:work processes running. A queue:work process may stop running for a variety of reasons, such as an exceeded worker timeout or the execution of the queue:restart command. For this reason, you need to configure a process monitor that can detect when your queue:work processes exist and automatically restart them. In addition, process monitors can allow you to specify how many queue:work processes you would like to run concurrently.
44
Where are Supervisor's configuration files stored?
/etc/supervisor/conf.d Within this directory, you may create any number of configuration files that instruct supervisor how your processes should be monitored. You should ensure that the value of "stopwaitsecs" in the config is greater than the amount of time consumed by your longest running job. Otherwise, Supervisor may kill the job before it is finished processing.
45
Once you have configured Supervisor, how can you update the Supervisor configuration and start the processes?
``` sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl start "laravel-worker:*" ``` In this example the configuration file would be called laravel-worker.conf, you obviously need to input the name of the specific configuration that you have created and want Supervisor to start.
46
Where are failed jobs stored?
Asynchronous jobs, that have exceeded their number of attempts, will be inserted into the "failed_jobs" database table. Synchronously dispatched jobs that fail are not stored in this table and their exceptions are immediately handled by the application.
47
How can you add a delay to a job being rerun after a failed attempt while starting the queue worker?
`php artisan queue:work redis --tries=3 --backoff=3` This would try job's in the redis queue 3 times and after every attempt wait for 3 seconds before the job is put into the queue again so that it couldn't potentially rerun right away. You can also just add this to the job class: ``` public function backoff(): int { return 3; } ``` And you can put an array of times into the return of this method so that the job will have increasing time spans before being put back into the queue
48
If a job failed, you may want to inform the user and / or revert any partial changes that the job has applied. Where can you define such behavior?
In the failed method of the job's class. The failed method receives a Throwable instance that caused the job to fail. ``` public function failed(?Throwable $exception): void { // Insert whatever you want your application to do as a reaction to the failure of a job } ```
49
How can you check all of the failed jobs that have been inserted into your failed_jobs database in the terminal?
php artisan queue:failed
50
What does queue:failed list?
It will list the job ID, connection, queue, failure time and other information about the failed job.
51
How can you manually put a failed job back into the queue again out of the failed_jobs database table?
php artisan queue:retry INSERT JOB ID(s)
52
How can you requeue all failed jobs?
php artisan queue:retry all
53
How can you delete a failed job out of the failed_jobs database table?
php artisan queue:forget INSERT JOB ID
54
How can you empty the failed_jobs table?
php artisan queue:flush
55
Which command removes failed jobs after a certain amount of time passing automatically?
`php artisan queue:prune-failed` By default, failed jobs would now get removed after 24 hours but you can also provide a custom amount of time: `php artisan queue:prune-failed --hours=48` This would now delete very failed job after 48 hours
56
Which environmental variable do you need to change in which way to instruct Laravel to discard failed jobs without storing them?
`QUEUE_FAILED_DRIVER=null` Now every failed job will just get discarded