Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implemented fastcgi_finish_request #113

Closed
wants to merge 1 commit into from

Conversation

dng-dev
Copy link
Contributor

@dng-dev dng-dev commented Oct 11, 2016

Implemented fastcgi_finish_request() to send response to the client as early as possible.
This function flushes all response data to the client and finishes the request. This allows for time consuming tasks to be performed without leaving the connection to the client open.

Flyingmana
Flyingmana previously approved these changes Oct 11, 2016
Copy link
Contributor

@Flyingmana Flyingmana left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the php documentation has a comment about blocking trough session, but I dont think sessions are really blocking. (actually they even have problems with multiple parallel requests writing into the session)
But that problem would still exist without this addition

// to the client open.
if(php_sapi_name() == 'fpm-fcgi' && true === function_exists('fastcgi_finish_request')){
fastcgi_finish_request();
}
Varien_Profiler::stop('mage::app::dispatch::send_response');
Mage::dispatchEvent('controller_front_send_response_after', array('front'=>$this));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this should go after line 186 in case for some reason someone wants to inject some additional content like an html comment with cache debug info or similar?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @colinmollenhour about moving the location. I also don't see the value is the true === bit, it just makes it harder to read.

@colinmollenhour
Copy link
Member

@Flyingmana Yes, session_write_close() can be used to close the session. I've been doing it this way for quite some time in index.php after Mage::run(...):

// Flush response before doing post-request processing
flush();
if (isset($_SESSION)) session_write_close();
if (function_exists('fastcgi_finish_request')) fastcgi_finish_request();

Wherever it goes just want to make sure it is after any events where a user might want to do some session modifications still.

@dng-dev
Copy link
Contributor Author

dng-dev commented Oct 12, 2016

I am not sure if this is right to echo stuff later. We use it in Production on this position for around 5/6 month with varnish and Ajax without any issues. Debug Stuff like Appserver Id we put as header.

@Flyingmana
Copy link
Contributor

Iam for fastcgi_finish_request before the event, because this event should not output any html anymore, as the closing html tag was already send, also I think there is another event before to attach html.

I also would not close the session there, as the events listening afterwards probably need to read from it. And the point I was trying to do was, parallel session writing already can happen, and people should avoid writing to the session anyways.

@colinmollenhour
Copy link
Member

because this event should not output any html anymore

Is this documented somewhere? I don't see why it can't be so just pointing out a potential BC breakage. Also, Magento is meant to be HMVC I believe so I think this needs to be moved out to a higher level.. For example:

https://github.com/colinmollenhour/Cm_Diehard/blob/master/code/Model/Backend/Local.php#L281

parallel session writing already can happen, and people should avoid writing to the session anyways.

Not sure I'm following you here.. What is "parallel session writing"?
The session_write_close() function happens anyway on shutdown, this method just triggers it sooner than later. So actually it would make sense to do it after fastcgi_finish_request(), but the advantage to calling it at all vs not calling it is that if you are using a backend which does locking then the lock will be released sooner. There is no reason to hold the lock on a session after no more assignments will be made to it.

// Flush response before doing post-request processing
flush();
if (function_exists('fastcgi_finish_request')) fastcgi_finish_request();
if (isset($_SESSION)) session_write_close();

@colinmollenhour
Copy link
Member

I propose putting it after this line so that it is guaranteed to be BC:

https://github.com/OpenMage/magento-lts/blob/1.9.2.4/app/Mage.php#L685

@Flyingmana
Copy link
Contributor

Flyingmana commented Oct 13, 2016

I looked a bit into the event, what it is used for. And we cant close the session before it. Also we have to expect that people make use of the session for such long processing cases we want to support here.

I will explain my point with the session_write a bit. Depending on the used backend and the implementation the Session can be a single "big" dataset. This is written on session_close. If the process still runs, and another one is already started, it has no access to the session changes of the long running process. And if the long running process runs longer then the 2. or even 3. process for this one session, it can happen, that it overwrites their session changes. I just wanted to mention this, I actually dont think we should add something for handling this, as the wished handling of this can depend a lot on the shop and the extensions doing such long running stuff. Some of them may require the session, others not.

regarding the fastcgi_finish_request() before or after the event. Is there even a later event which is commonly used for longer running processing?
Also, the event is already called "..._send_response_after" so it should be expected, the response is already sent. Any extension which now would output something, would do this knowing, the closing tag was already output, and would be willing to create broken html.
There may be extensions doing this, but they are probably edge cases and causing broken html.
So this BC break will very likely only break already broken stuff.

@colinmollenhour
Copy link
Member

Please read again: If the user doesn't want to output more data after the response is sent, calling fastcgi_finish_request inside of the front dispatch() call stack is still bad because the HMVC pattern allows the "response" to be not necessarily flushed which is exactly what I do here in my cache extension:

https://github.com/colinmollenhour/Cm_Diehard/blob/master/code/Model/Backend/Local.php#L281

Maybe I'm the only one that ever did this with Magento, but still there is no harm in moving it up the call stack one frame..

// to the client open.
if(php_sapi_name() == 'fpm-fcgi' && true === function_exists('fastcgi_finish_request')){
fastcgi_finish_request();
}
Varien_Profiler::stop('mage::app::dispatch::send_response');
Mage::dispatchEvent('controller_front_send_response_after', array('front'=>$this));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @colinmollenhour about moving the location. I also don't see the value is the true === bit, it just makes it harder to read.

@seansan
Copy link
Contributor

seansan commented Feb 8, 2018

Pfoe. That was hard to read ;)
Is this still relevant? And does it solve a real bug/problem?

@colinmollenhour
Copy link
Member

Yes, I think it is a good improvement, just belongs in a different location.

@tbaden tbaden added the code change requested For Tickets where changes in code are needed, but seem mostly fine label Jun 1, 2019
@sreichel sreichel added Component: Core Relates to Mage_Core enhancement labels Jun 5, 2020
@addison74
Copy link
Contributor

addison74 commented Feb 23, 2021

There are situations when the client doesn't wait for server response or resets the connection (e.g. bots). In this case Apache/Nginx error logs will fill up with lines like this one:

[Fri Jan 09 16:50:00.093819 2015] [fcgid:warn] [pid 26063] (104)Connection reset by peer: [client <IPv4_ADDRESS>:9784] mod_fcgid: ap_pass_brigade failed in handle_request_ipc function

Many system administrators trying to find a solution start to adjust FCGI parameters in Apache or PHP configuration files but this doesn't solve the issue. Also it is not coming from a slow script in Magento as a few stated in Forums. If they will check the access logs they will understand only a few IP's generate this issue from time to time those IP's which are banned for SPAM or running bots.

As I understand this commit comes to solve an issue like this in Magento. If it works without generating any trouble indeed it is an improvement.

colinmollenhour added a commit to colinmollenhour/magento-lts that referenced this pull request May 3, 2021
…mpleted rendering. Add core_app_run_after to allow events to occur after response is sent. Refs OpenMage#113
@fballiano
Copy link
Contributor

Yes, I think it is a good improvement, just belongs in a different location.

what would the location be now? so that we could modify the PR and move it forward ;-)

@addison74
Copy link
Contributor

This PR needs to be rebased to OpenMage:1.9.4.x.

@fballiano fballiano changed the base branch from 1.9.2.4 to 1.9.4.x June 3, 2022 08:28
@fballiano fballiano dismissed Flyingmana’s stale review June 3, 2022 08:28

The base branch was changed.

@addison74
Copy link
Contributor

I would close this PR in favor of #1592. Let's see some 2 - 3 opinions too.

@colinmollenhour - what do you think about?

@luigifab
Copy link
Contributor

luigifab commented Mar 4, 2023

I vote for 1592.

fballiano added a commit that referenced this pull request Apr 5, 2023
…vent (#1592)

* Explicitly end the request and close the session after the app has completed rendering. Add core_app_run_after to allow events to occur after response is sent. Refs #113

* Update EVENTS.md

---------

Co-authored-by: Fabrizio Balliano <fabrizio.balliano@gmail.com>
fballiano added a commit that referenced this pull request Apr 5, 2023
…vent (#1592)

* Explicitly end the request and close the session after the app has completed rendering. Add core_app_run_after to allow events to occur after response is sent. Refs #113

* Update EVENTS.md

---------

Co-authored-by: Fabrizio Balliano <fabrizio.balliano@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
code change requested For Tickets where changes in code are needed, but seem mostly fine Component: Core Relates to Mage_Core enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants