Send to background activity before response is sent

I've read a lot, but everything I've tried doesn't work at all. I will try to briefly explain my problem and see if there is a solution. I am using a web application developed with Yii.

Process:

- 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.

      

This whole process takes about 20 segments. It takes too long for the user to leave the page. So I need the user to get "OK" immediately after saving their information. Something like that:

- 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 the response is sent, the process continues to run in the background.

I have 3 methods in the model: - method1 -> save user information. - method2 → send information. - method3 -> built and sent the report.

In the controller, I have a method that is called by the website, that submits a form, that starts the whole process, and finally submits "OK" to the internet.

Something like that:

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 lights in that order, but 2 and 3 are executed in the background, so the response can be sent immediately after the user information is saved (method 1).

Hopefully I'll explain myself and I can find a solution. Thanks in advance.

+3


source to share


2 answers


You cannot break a linear process. But to support your type of requirement, you will need Queing tools like ( ZeroMQ , BeanstalkD , GearMan , etc.).

These tools are very lightweight, multi-threaded, and excellent. In my current project, I am using BeanstalkD. We had a request to send a message to 10,000 users, but we don't want the sender to wait.



All the best!

+1


source


One way, suggested by PHP itself, is to use flush()

and ob_flush()

.

This means that you are exactly doing what you are looking for: send the result to the agent (browser) and continue executing whatever PHP comes after.

Unfortunately, this 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, it may not be as easy as in the above example depending on the above factors. Here is an excellent read on how to ensure content is sent to the browser using PHP as CGI and Apache web server.

If this approach becomes impossible in your particular scenario, there is another example of background execution that I won't dwell on here, but it will look something like this:

0) Write a PHP script that can process data in CLI mode as desired 1) Execute method1 2) Execute script in background, eg. exec('/usr/bin/php yourscript.php?userData1='. $someData . '&userData2=' . $otherVar . ' &')

(Note at &

the end of the command, this sends the process to the background, so it exec()

returns immediately.) 3) Submit a response.

0


source