What is a Job in Laravel?
There’s a lot to unpack here.
First of all, jobs are various tasks that we get Laravel to perform. More specifically, they are things to do in the background, so they’re often used for something that could take a while.
As developers, we can create custom jobs for pretty much anything we’d like, and will commonly do so for I/O intensive tasks like importing/exporting large sets of data. It should also be noted that some other commonly-used parts of Laravel can be quite easily turned into jobs, such as notifications. Notifications are short messages that Laravel can send out. We commonly use them for sending emails and SMS messages.
Laravel presents us with queues that we can use in order to line up a series of jobs. When doing so, they’ll be processed sequentially. The mechanism for doing this is flexible enough to let you decide on the tech used for storing your queues (DB/Redis/Beanstalkd/SQS), and can easily be set up in a dev environment too.
The worker is a separate process that is dedicated to processing the jobs in your queue. Adding a worker process will tie all these pieces together, and you’ll end up with improved UX, scalability, and flexibility, all while keeping standardized code that’s elegant to read.
Improved User Experience (UX)
The improvements to user experience are realized by virtue of separating these tasks into jobs that are run in a different process. Sometimes the jobs being run are necessary for the system to work, but don’t necessarily need to be run instantaneously.
A good example of this would be a site that is publicly accessible. Let’s say our site is one that anyone can visit and fill out a registration form. Let’s also assume that all site administrators will receive an email notification every time someone new registers on the site. If this is a popular site, it’s likely that there are several administrators.
It doesn’t seem right that a user would fill out the registration form, hit next, and then have to sit and wait for the site to send out all the emails before redirecting the user to the next page, right? This is a perfect example of when we can queue jobs for the worker to take care of, and send our user on their way.
Essentially, we’re taking what was a very linear process, breaking it into parts, categorizing those parts based on when they need to be run (now vs soon), and allowing them to be run in parallel.
Since we can run workers as separate processes, it becomes possible to monitor their individual performance, and scale up as needed. Multiple workers can be set up, and they can even be distributed across multiple servers in your cluster to optimize performance.
A lot of flexibility becomes available to us when we use jobs/queues/workers as they were intended. We can have jobs set up so that they will be attempted multiple times in the event of a failure. This can be specified globally on our worker process, or even on a per-job basis.
Jobs are also capable of using middleware. This is particularly helpful when you have multiple jobs that need to behave in a similar manner. We’ve taken advantage of using job-based middleware like this before for making sure that SMS messages only get sent out during specific daytime hours. It’s possible to set up the middleware to check the current time, and reschedule the job for a later time if it doesn’t match certain criteria. Now that we have this middleware defined, we just have to specify if we want it to be used on a per-job/notification basis.
Even though Laravel’s system is robust, it is fairly simple to set up. How you set up your site to use jobs/queues/workers will depend on the various technologies you use. Lots of pertinent details can be found in the official documentation. Regardless of the technologies you choose, you’ll have a lot of power at your fingertips. You’ll be able to prioritize and schedule jobs, they’ll be well documented and organized, and you’ll even gain logging of failed jobs as well. If you find yourself in a situation where you have failed jobs, and you want to do something about it, there are even options to retry them!
There aren’t many gotchas to using jobs/queues/workers, however there are a couple things I think are important to bring up. First of all, when you’re configuring your setup, you’ll need to specify which drivers you’ll be using for establishing a connection to your queueing tech. Some job-processing functionality is tech-specific. For instance, the
block_for configuration option is only available for redis queues at the time of writing.
The other note I’d like to add is because the worker process will usually be started via a command such as
php artisan queue:work, you’ll want to make sure you restart that process after making changes to the codebase.
There are a lot of benefits that come from using a separate process to handle your queued jobs, and these features are all baked-in to the Laravel framework. Even if you’re only using this functionality for your notifications, it’s well worthwhile. To top it off, from a coder’s perspective, very little changes in the code you write to send your notifications. Are you using workers already? If not, then what are you waiting for?