Deep Dive Into Laravel Queue Job

Tram Ho

Laravel is a php framework out of box that is used by a lot of people, it gives us a lot of convenience but sometimes it limits us to understand the lines of code we are writing.

Queue Job in Laravel is something we use often, but there are many questions about it that have not been answered, if you are having the same questions as me, let’s find out:

  • What is Queue? What is a job?
  • We can use Redis, Mysql … to save the Job. So how is the job saved, in what form? Is the whole app instance, how can it work: v? ** the stupid question I’ve asked =))
  • Why is the same job that if running sync can access the session, request but if sync is not accessible.

1. What is Queue? What is a job?

Queue

Queue as you learned in school is a type of data structure, with FIFO mechanism. It’s the same for the Queue job here and the one that’s saved is the Job.

One thing many people often misunderstand is that Queue Job will execute the Job (I thought so: v), this is wrong, Queue Job is simply a Queue to save the Job.

And the Queue Module in laravel is a tool that helps us communicate with that Queue Job, such as Redis Queue.

Job

The job here is simply the same information as the Job Class (just namespaced name) you have declared, the data in that class (for the job job), along with the construct param that you pass into will be saved to Redis, database, file or whatever driver you choose.

2. How Queue Job work

** This part will be the prank part about how the queue job in laravel works, gathered from many sources and many people.

For example, suppose that Mr. A uses the export csv function in our system, instead of executing concurrently and making him wait until the response is received without turning off the tab.

Then we will throw the heavy csv export job into the queue and immediately return a response with a message: “The file export process has started, we will notify you when it is done”.

When completed, notify Mr. A of the results.

I will list the main components we will learn:

  1. PHP Process – a php process is created to handle the above request, and of course it will also create a laravel instance
  2. Worker – another php process – contains another laravel app instance – the difference is that it has been initialized, not killed when the request is completed.
  3. Queue – 1 queue containing namespace name of job and data, stored in Redis.
  4. Job – Class and data initialization

Here I will describe how the queue job works with the system where the process executes the http request and the woker (the process that executes the job) with the same server, the queue job is redis and the same server is also.

The first is Worker, which is a php process, will be launched first, for example, we are using the ExportCSV queue to run the csv export task, the Worker to work with the queue will be launched by the following command php artisan queue:work --queue=ExportCSV

Here, we will first launch the app through the artisan file instead of public / index.php and instead of using the Http Kernel as when processing the http request, the laravel will use the Console Kernel, which we call worker.

Please read the following articles before continuing.

https://divinglaravel.com/queue-workers-how-they-work

https://divinglaravel.com/preparing-jobs-for-queue

https://divinglaravel.com/pushing-jobs-to-queue

I added a bit about how a job is handled by worker from queue and how it works. In the article “Preparing jobs for queue” the author said he would explain in the next section but did not see it anymore.

Why do we pass a different class as the “job” parameter? Queue [email protected] is a special class Laravel uses while running object-based jobs, we’ll look into it in a later stage.

In laravel we can pass jobs in 2 formats: object and string

String

Object

Please review the createObjectPayload and createStringPayload functions in vendor/laravel/framework/src/Illuminate/Queue/Queue.php to see how the two types of data will be formatted.

And now let’s look at the fire function in Class Job

and the JobName :: parse function ($ job)

Str :: parseCallback function

If it’s a String job with format

Then the list($class, $method) = JobName::parse($payload['job']); statement list($class, $method) = JobName::parse($payload['job']); will immediately return $class = 'ExportCSV' và $method = 'handle' , an instance of ExportCSV will be initialized with the resolve function from the container, and the handle will be called directly.

But with Object is different, let’s review the format of the job object:

When $job->fire(); If called, the actual statement to be executed is:

(new IlluminateQueueCallQueuedHandle)->call($job, $job['data'])

Now let’s look at the call function.

These lines:

is to set the $ job property in Trait InteractsWithQueue, which is reasonable, but why with String Job we do not need the set that Object Job needs? (Previously, I wrote wrongly, this will check later, this is likely a bug, InteractsWithQueue will probably not work with String Format).

What we really need to care about is this:

$this->resolveHandler($job, $command) this line is to get the command handler (the old job name from version 5.0 https://laravel.com/docs/5.0/bus ), you can understand that it is job is split into 2 parts command (data part) and handler (processing part) (learn here https://martinbean.co.uk/blog/2019/03/21/command-bus-in-laravel/ ).

And for any regular Job you use, not “command”, the function

will always run into else and here the job is executed at the current process (worker). If you do not understand the last line, read here https://jeffochoa.me/understanding-laravel-pipelines?source=post_page—–a7191f75c351————— ——-

I’m a little rambling about the process job, the other part is pushing the job to the queue or pulling the job from the queue in the worker, you can read in the links I wrote above.

At this point, surely you have a clear understanding of the Queue Job System in laravel, next we will learn about the 3rd issue that I mentioned above.

3. Access session, request in queue job

When you write:

Because the queue job will be run in another process, the objects that are created each time the request is processed, such as the request or the session in the worker and the process in which you push the job, are different.

In order for the queue job to access those values ​​you need to pass them in. You can still use normal type-hint injections.

Another thing is how to access files in requests in the queue

The file will be deleted from the temporary directory at the end of the request if it has not been moved away or renamed. – https://www.php.net/manual/en/features.file-upload.post-method.php

Therefore, if you do not want to have to pass the whole file’s data in base64 format or something to the queue (which will consume a lot of resources), then move that file.

Share the news now

Source : Viblo