yii2 icon indicating copy to clipboard operation
yii2 copied to clipboard

on AfterSend event blocks sendig the view

Open B0rner opened this issue 2 years ago • 7 comments

The on AfterSend event should run, after the view was send to the browser. But the browser seams to recieve the view after the AfterSend event is finish. It looks like the event behavior is lik "on BeforeSend", not "on AfterSend"

What steps will reproduce the problem?

Adding the following code block into the web.php

'components' => [
	    'response' => [
	        'class' => 'yii\web\Response',
			'on afterSend' => function ($event) {
                                sleep(10);
				Yii::debug('after send');
			},
         ]

What is the expected result?

Ever request from an browser returned immediately. The user/browser received the view, after it is rendered, without 10 seconds delay. I expect, sleep(10) is not blocking the request.

What do you get instead?

The request from the browser stops for 10 seconds. After the afterSend-sleep ist finish, the application sends the view/the brwoser receives the view. It looks like tihs event is working like an "on beforeSend" not like an "on afterSend".

Additional info

Q A
Yii version 2.0.46
PHP version 7.4.14
Operating system Yii2 docker container on ubuntu 20.04

B0rner avatar Dec 05 '22 15:12 B0rner

What's your use-case here? Post-processing some stuff when your content is rendered?

Output flushing is heavily dependend on your setup, see also comments:

  • https://www.php.net/manual/en/function.flush.php
  • https://www.php.net/manual/en/function.ob-flush.php

schmunk42 avatar Dec 08 '22 14:12 schmunk42

Thanks for posting in our issue tracker. In order to properly assist you, we need additional information:

  • When does the issue occur?
  • What do you see?
  • What was the expected result?
  • Can you supply us with a stacktrace? (optional)
  • Do you have exact code to reproduce it? Maybe a PHPUnit tests that fails? (optional)

Thanks!

This is an automated comment, triggered by adding the label status:need more info.

yii-bot avatar Dec 09 '22 09:12 yii-bot

I've run into this problem before. Use case: not a response related post processing, example

  • sending sentry events that have not yet been sent (slow or unstable server)
  • deleting temp files created during the request
  • expired file cache processing (site level)

If the request is fastcgi, then fastcgi_finish_request() is recommended.

# after send event
fastcgi_finish_request();
# request is ended by HTTP level
sleep(3600)

kamarton avatar Dec 10 '22 02:12 kamarton

@kamarton so that's buffering that's not Yii-related, right?

samdark avatar Dec 10 '22 09:12 samdark

Symfony is using that code to achieve it

public function send(): static
{
    $this->sendHeaders();
    $this->sendContent();

    if (\function_exists('fastcgi_finish_request')) {
        fastcgi_finish_request();
    } elseif (\function_exists('litespeed_finish_request')) {
        litespeed_finish_request();
    } elseif (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true)) {
        static::closeOutputBuffers(0, true);
        flush();
    }

    return $this;
}

This is handy to proceed with some heavy processing after the response is sent to a user. Yii is not offering such solution.

bizley avatar Dec 10 '22 11:12 bizley

I think we can do it as well.

samdark avatar Dec 10 '22 18:12 samdark

What's your use-case here? Post-processing some stuff when your content is rendered?

Output flushing is heavily dependend on your setup, see also comments:

  • https://www.php.net/manual/en/function.flush.php
  • https://www.php.net/manual/en/function.ob-flush.php

That is strange: I wrote the answer 2 days ago, but it's not in the issue timeline here.

My usecase is processing long running things, related to the request without the user needs to wait for, like calculating and writeing statistic data. In my case i have a bit longer runnig mysql-query with joins für statistic data and data-postrocessing for features.

Flushing the data using ob-flush did not solved the problem.

B0rner avatar Dec 11 '22 15:12 B0rner