Reputation: 33
I've been reading a lot but everything I've tried didn't work at all. I'll try to briefly explain my problem and let's see if there's a solution. I'm using a web app developed with Yii.
The process is:
- Someone send a form to our web.
- Save user info in our DB
- Send that info to another web.
- Build a log and send it to admin
- 'OK' is sent to the user.
All this process takes about 20 seg. Too long before the user can leave the page. So the thing is I need the user to receive the 'OK' right after his info is saved. Something like this:
- Someone send a form to our web.
- Save user info in our DB.
- 'OK' is sent to the user.
- Send that info to another web.
- Build a log and send it to admin.
I need to make the process asynchronous so after response is sent, the process keep running in the background.
I have 3 methods in the model: - method1 -> save user info. - method2 -> send info. - method3 -> built and send report.
In the controller I have a method that is called by the web who sends the form, which fires all the process and finally sends the 'OK' to the web.
Its something like this:
public function actionAux(){
$form = new Form();
$form->method1;
$form->method2;
$form->method3;
$this->response(); // This send the 'OK'
}
Well, I need these methods to be fire in that order but 2 & 3 run in background so response can be send right after user info is saved (method1).
Hope I have explain myself and I can find a solution. Thanks in advance.
Upvotes: 3
Views: 163
Reputation: 15351
One way offered by PHP itself to solve this is to use flush()
and ob_flush()
.
This meant to do exactly what you are looking for: send the output to the agent (browser) and keep executing any PHP that comes after.
Unfortunately whether this works or not depends on many factors, read here.
If all the conditions are present for this mechanism to work as expected you could do something like this:
$form = new Form();
$form->method1();
$this->response();
ob_flush();
flush();
$form->method2();
$form->method3();
However, this could not be as simple as in the example above depending on above mentioned factors. Here is a great reading on how to make sure content is sent to the browser using PHP as CGI and Apache web server.
If this approach becomes impossible in your particular scenario, there's still another involving background execution which I'm not going to detail here but it would go something like this:
0) Write a PHP script that is able to process data in CLI mode in the desired way
1) Execute method1
2) Execute the script in background, e.g. exec('/usr/bin/php yourscript.php?userData1='. $someData . '&userData2=' . $otherVar . ' &')
(note the &
at the end of the command; this sends the process to background so exec()
returns immediately.)
3) Send the response.
Upvotes: 0
Reputation: 990
You can not break any linear process. But to support your type of requirements, you need Queing tools like (ZeroMQ, BeanstalkD, GearMan etc...).
These type of tools are very light, Multi threaded and excellent durability. In my current project, I'm using BeanstalkD. We had requirement to send message to 10,000 Users but don't want sender to wait till.
All The best !!
Upvotes: 1