How to call a function without wait it finishes in php? - php

I use Laravel framework in my project.
I need call a function in PHP but I don't need wait for this.
For example:
public function payment($Authority)
{
if (test == 1)
$this -> one($Authority); // don't wait for this call.
return view ("site.payment");
}
private function one($Authority)
{
// php code
// python code
}

Laravel has a queue job system. You could create a job to call that code and have your payment method dispatch the job to the queue for processing. (assuming you don't use the sync driver).
"Queues allow you to defer the processing of a time consuming task, such as sending an email, until a later time. Deferring these time consuming tasks drastically speeds up web requests to your application." - Laravel 5.3 Docs - Queues
public function payment($Authority)
{
if (test == 1) {
// send to queue for processing later
dispatch(new SomeJob($Authority));
}
return view ("site.payment");
}

You can try to use PThreads extension (http://php.net/pthreads):
<?php
// create your own class from Thread
class MyWorkerThreads extends Thread
{
private $workerId;
private $authority;
public function __construct($id, $authority)
{
$this->workerId = $id;
$this->authority = $authority;
}
// main function
public function run()
{
echo "Worker #{$this->workerId} ran" . PHP_EOL;
echo $authority;
// make some long run tasks
$html = file_get_contents('http://google.com?q=testing');
}
}
...
$worker = new WorkerThreads($i, $Authority);
// start new thread with long run task
$worker->start();
...
// You can wait for the job to be finished at any time, using join
$worker->join();

you can call another process to run the code with proc_open. You also can write it into a artisan command, then call the command run in another process.
Here is a example for use proc_open()

Related

Laravel Job - best way to execute a command at start and at fail of every job

I have a piece of code that takes the user (passed into the job constructor) and notifies the user via a websocket to the job status.
It is effectively one line that needs to be added to the start of the handle method (before the job starts), one to the end of the handle method (after the jobs has completed) and then on in the fail method.
Other than adding this to each job manually, what is the best way to do this? Something like a trait, middleware etc. but I don't think either of these will work.
One way could be extending the job/command class like:
class MyJob extends Job {
public function handle() {
try {
do_stuff_at_start();
$this->process();
} catch (Exception $e) {
do_stuff_when_fails();
}
abstract public function process();
}
and all Your jobs could implement process() method that is responsible for handling logic. Just a loose idea - not sure if it fits Your needs.

How to process multiple task in codeigniter cli at the same time

I am not sure if this is doable or not. I am running cron job to process data and they are all independent of each other.
For example i have a data [x,y,z] and i have a method in the parent controller that does what it needs to do. Process takes little long and hence my queue is piling up since it is doing one at a time. I tried forking process but it loses connection to the mongo database. Therefore, I had to remove fork for now but please let me know if i can reconnect.
Pseudocode
MyTools.php
class MY_Tools extends CI_Controller {
...
public function process($item) {
Make curl request
Update database for the item
}
}
Tools.php
class Tools extends MY_Tools {
...
public function getAllDate() {
$data = fetchDataFromDB() => [X,Y,Z]
$i = 0
while ($i < sizeof($data) {
$this->process($data[$i]);
$i++;
}
}
}
if i can do this without waiting for another process to complete and just keep on going, that will be great
In addition, I am using php7
cimongo library for codeigniter and https://github.com/alcaeus/mongo-php-adapter
Possible Solution
For php7, i have used this for gearman installation
https://techearl.com/php/installing-gearman-module-for-php7-on-ubuntu
Codeigniter gearman library that I used : https://github.com/appleboy/CodeIgniter-Gearman-Library
To overcome static method accessing parent controller, use singleton method
I was struggling with this for a bit and hopefully it will help someone
Example
class MY_Tools extends CI_Controller {
private static $instance;
function __construct() {
parent::__construct();
self::$instance =& $this;
}
public static function get_instance()
{
return self::$instance;
}
}
To Access
MY_Tools::get_instance()->YOUR_PUBLIC_METHODS();
Hope this can help someone

Background Processing using pthread in php

I am trying to implement muti-threading in php using pthread to send emails. The basic idea here is to send email as a background job so that users dose not have to wait for the task to finish.
I have a service that users PHPMailer to send emails and its working fine. I am using the following code to muti thread
class ThreadWorkerService extends \Thread {
private $_runMethod;
private $_vars;
private $_autoloderPath;
function __construct($vars) {
$this->_vars = $vars;
$reflector = new \ReflectionClass('Composer\Autoload\ClassLoader');
$dir = dirname($reflector->getFileName());
$this->_autoloderPath = $dir . "/../autoload.php";
}
public function setRunMethod($method) {
$this->_runMethod = $method;
}
public function run() {
if (!class_exists('Composer\Autoload\ClassLoader')) {
if (file_exists($this->_autoloderPath )) {
require_once( $this->_autoloderPath );
} else {
echo "autoloder not found";
}
}
$method = $this->_runMethod;
$results = $method($this->_vars);
}
}
$storage = new \Threaded();
$storage['emails'] = $emailArray;
$storage['config'] = $config;
$threadWorker = new ThreadWorkerService($storage);
$threadWorker->setRunMethod(function ($vars) {
$emailArray = $vars['emails'];
$config = $vars['config'];
$emailService = new \MyServices\EmailService($config);
$emailService->sendAllEmails(true, $emailArray);
}
});
$threadWorker->start(PTHREADS_INHERIT_CONSTANTS);
The issue here is that the tread dose not execute if i don't use
$threadWorker->join();
which eliminates the whole purpose of muti-treading in this scenario, what I want to know is, if it is possible to keep the child thread alive even when the parent process is complete. I have even tried detaching the thread with no luck.
I am familiar with on how to do it with messaging services like RabbitMQ, but I want to keep the application independent.
The issue here is that the thread does not execute if I don't use: $threadWorker->join();, which eliminates the whole purpose of multi-threading in this scenario.
It is likely the case that the main thread's stdout, or some other dependency, is being closed or destroyed before the thread gets to execute.
Taken from the PHP manual for Thread:
Warning: Relying on the engine to determine when a Thread should join may cause undesirable behaviour; the programmer should be explicit, where possible.
You don't need to join immediately, but it is advisable to join explicitly.
The following example code illustrates the problem:
<?php
class Test extends Thread {
public function run() {
sleep(1);
echo "Thread\n";
}
}
$test = new Test();
$test->start();
echo "End\n";
?>
CPU speed permitting, the main context will begin to destroy the Thread before the Thread gets to echo.
You will normally get the output:
End
Thread
However, if the code is more complex, for example, code that manipulates dependencies set in the constructor of the Thread, those dependencies might have already been destroyed by the time they are used.
A last ditch attempt to join implicitly is made (in the most recent versions of pthreads), but you cannot rely on destruction order being compatible with your expectations, and so explicit join is preferable.
Noteworthy: The most recent versions of pthreads (PHP7+) prohibit execution anywhere but CLI; If this is code that is being executed at the frontend of a web server, you will need to rethink your architecture.

How to use threading in Laravel to run stored procedures

I want to use php threads for asynchronously loading a function that executes a mysql stored procedure. The stored procedure takes a lot of time to load, so keeping it asynchronous is the only optimal solution, I found.
I have no idea on how to bring the threading inside Laravel. Laravel has queues but I want to do it directly in script with thread.
What i've done to approach a similar issue (I've done it in a sync command) is to create a class that extends from Thread and call it from the laravel code.
The class in your case might be something like this:
class LaravelWorker extends Thread
{
private $object;
public function __construct($object)
{
$this->object = $object;
}
public function run()
{
$object->runProcedure();
}
}
And you can call it at your code such as this:
$object = new ObjectWithProcedure();
$threadedMethod = new LaravelWorker($object);
$threadedMethod->start();
If, for some reason, you need to wait until the $threadedMethod finishes, you can do
$threadedMethod->join();
(more_code...)
And the more_code section will only execute once $threadedMethod has ended.
Hope it helps!

PHP thread do not end

I tried to implement multithreading in php to fetch data from a data source parallely.
But in the process, the threads i create to fetch the data continue to remain in the memory, even after the fetching.
This is the class that i call
class ClassName extends Thread {
public function __construct($i){
$this->i=$i;
}
public function run(){
// functionCallToDataSource($this->i);
}
}
and i call this class here (in a loop).
$workers = new ClassName(parameter);
$workers->start();
$workers->kill(); //this isnt working
This kill() doesnt seem to work for me, as the memory is not reduced after the functions have been performed.
I have to restart my server to free the blocked memory

Categories