How to create thread in laravel 5.6? - laravel

In need run other function without stop.
How to use thread in laravel 5.6?
For example:
public function index()
{
$id = "123456";
$this->run_bot($id);
return view("index");
}
Funtion run_bot it takes about 10 minutes !!!!
I need run run_bot in a thread.
How to craete thread in laravel 5.6?

Look into Symfomy's Process Component.
As an example, you can start the process and then later wait for it to complete:
$process = new Process('ls -lsa');
$process->start();
// ... do other things
// this is optional, you don't need to wait if not necessary
$process->wait();

The solution you are looking for is how to run asynchronous jobs. This can be done with a queue service (like AWS SQS) and the Laravel queue worker.
It will allow you to send the job (really light work so it's really speed). And then, asynchronously, retrieve and execute the job.
Everything you will need to know is here :
https://laravel.com/docs/5.6/queues
Let me know if it helped you :)

Related

Getting PID of queue in Horizon with Laravel

For different reasons I need to read the PID of the queues of a supervisor in Laravel Horizon. The problem is that I can't find the information in the library.
I'm able to retrieve all supervisor like this:
public function index(SupervisorRepository $supervisors){
$supervisors = collect($supervisors->all())->sortBy('name');
return $supervisors;
}
or all workload (queue) like this:
public function index(WorkloadRepository $workloadRepository){
$workload = collect($workloadRepository->get())->sortBy('name')->values()->toArray();
return $workload;
}
but I don't see how I can get the PID of queue by the repository, last but not least I can't run shell command on my server so I must get it by either accessing Redis or Laravel Horizon.
Turn out you can't get it from horizon, you need to get it by questioning your os

Laravel Queue affecting the execution time of API function

I have an API function that stores pdf file to my s3 bucket and then sends email with the pdf file as an attachment.
Since this is my first time, I got confused because from what I understood, jobs executes from the background, thus, it should not affect the execution time of the function.
But instead, having these jobs makes the execution time almost 8 seconds.
Here's my function
$is_exist = CoachingApplication::where('user_id', $userID)->first();
if ($is_exist == null) {
$application = new CoachingApplication();
$application->user_id = $userID;
$application->applicant_name = $applicantName;
$application->attachment = $filename;
$application->instrument_rate = $instrumentRate;
if ($application->save()) {
if ($filename !== 'none') {
StoreBucketJob::dispatch($userID, $filename, $attachment_fileArray)->delay(Carbon::now()->addSeconds(3));
}
SendEmailJob::dispatch($userID, $userName, $userSlug, $userEmail, $filename)->delay(Carbon::now()->addSeconds(3));
}
}
If I remove these jobs, the function's execution time is 469ms.
Any idea why these jobs affects the api's execution time?
By default, the queue driver is setup to sync and you are probably using it.
This queue driver means your jobs will be executed within the current process and will not be dispatched in an actual queue (which is pretty useful during development).
A good way to be 100% sure that your job are indeed executed synchronously would be to just put a dd("ok"); at the first line of the handle method inside your job. handle is only executed when the job runs, not when it is dispatched.
The queue driver can be updated by editing your .env file (look for QUEUE_CONNECTION).
There are many queue drivers available and some requires additional dependencies, so you should check out the documentation available https://laravel.com/docs/8.x/queues.

How to manually run items from the Jobs table in Laravel (for testing)

I am trying to test that some data gets populated on a page that is done by a job. In my testing environment, the queue isn't running.
Is there any way to manually run the jobs from a function in a controller? I have retrieved all Jobs from my database by doing the following:
$allJobs = Jobs::all();
foreach ($allJobs as $job) {
// $job->handle(); ????
}
What I would like is to iterate over each job and process them myself. My test suite can wait for these jobs to be processed. I can't seem to find any documentation about this. Thanks!
If the goal is to be able to write tests for your jobs, it is fairly simple:
public function testJobsEvents()
{
$job = new \App\Jobs\YourJob;
$job->handle();
// Assert the side effect of your job...
}

How to run Laravel Queue without using artisan or shell?

I tried php artisan queue:work, its runs great, the website no freezing, but how to run programatically via Controller? i run Artisan:call('queue:work') but its freezing (waiting the queue to finish) and end up gateway timeout, but the queue run successfully though.
Any suggestion?
Queues allow you to defer the processing of a time-consuming task, such as sending an email, until a later time.
So executing the queue worker from controller actually negate the purpose of the queues. Explain your exact use case in question to provide more details.
Try this in your controller function
use Symphony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessTimedOutException;
try {
$process = new Process(your artisan command,
null,
your environment,
[],
timeout(ex: 60000),[]);
$process->run();
} catch (ProcessTimedOutException $e) {
// you can show some flash message
// OR
return Response::json(['message' => 'some message'], 'desire response code');
}
In your case, you need to do some font-end hack, run this controller function as ajax and make some loading. And stop the loading after your desire time is pass.
This is not a best approach, you should not run queue process from controller, you should let your server to do this process by using supervisor, etc…
https://laravel.com/docs/5.1/queues#supervisor-configuration

Manual Release of Job fails in laravel

I'm currently using Laravel's Queue to process a job. I need to release this job some point in time but it runs immediately even if I implemented release(). Is this a bug of laravel or did I miss something?
public function handle()
{
$this->release(120);
var_dump('Hello World!!'); ---> This was displayed right after I called the Job
}
Also, QUEUE_DRIVER is set to RabbitMQ
I don't think release is what you want. Release is that is will be put back into the queue after 120 seconds of being worked at.
If you want it to be in the queue for at least 120 seconds you can used delayed dispatching. https://laravel.com/docs/5.4/queues#delayed-dispatching
For reference:
$job = (new MyJob())->delay(Carbon::now()->addMinutes(2));
dispatch($job);

Resources