FastCGI on IIS7... multiple concurrent requests from same user session? - php

Caveat: I realize this is potentially a server configuration question, but I thought there might be a programmatic answer, which is why I am posting here...
Running PHP on Apache, our users were able to issue multiple concurrent requests (from different tabs in the same browser, for example).
Since moving to FastCGI under IIS, this is no longer the default behavior. Now, when a user starts a request to the server and the browser is waiting for a response, if they open a new tab and start another request, the new request is not processed by IIS until the previous request is completed by IIS.
If the user opens a different browser and logs in (which starts a new session for that user), concurrent requests are possible.
My question is: is there a way to configure FastCGI/IIS7 that will allow multiple concurrent requests from the same user session? If not, is there an alternative that would allow this?

The problem is the session mechanism, most likely. PHP Sessions, by default, since they are using the file system, have to wait for the session file to be closed before they can open them again. Therefore, subsequent requests for the same session wait on prior requests, or to give another example in addition to yours, if you had a frameset page (shudder) with three frames, each referencing the session, they would all load one at a time, because each page would have to wait for the session mechanism.
Possible Solutions:
As soon as you're done with the session, call session_write_close()
Implement a custom DB handler which utilizes the database instead of the file system.

It looks like I'm out of luck, at least running PHP under FastCGI on Windows: PHP FastCGI Concurrent Requests

Related

IIS Website - unable to load other pages while cron/ long execution running

Hoping someone has some ideas around what to do with this.
We have a application thats PHP based hosted in IIS.
There are a number of functions that need to run which can be running for 10mins+. The problem I have is that if I run one of these functions in my web browser. If I open another tab and try to access the site while that is happening then it just sits loading until the long process finishes and then it loads the page.
I guess this is more of a multi session thing to my browser? Is there some easy option in IIS I can change that will let it load the other pages as normal? Or is this a browser thing?
It seems if I open an in private window at the same time, that will load normally.
The issue is related to the session. by default PHP session use a file system.so that has to wait for the session file to be closed before they can open new. Therefore, subsequent requests for the same session wait on prior requests.
To resolve the issue you could try the below things:
-close the session when you are done with it by using the session_write_close()
-Implement a custom DB handler which utilizes the database instead of the file system.
Reference:
FastCGI on IIS7... multiple concurrent requests from same user session?

Symfony not serving concurrent requests

My problem is that my Symfony application running on a remote machine with Apache/2.4.6 (CentOS) PHP/5.6.31 MySQL 5.7.19 does not handle concurrent requests. Meaning that when asking for two different pages at the same time. First one has to finish before second one can be rendered.
I have a another site on the same server written in plain Php which has no problem rendering as many pages as possible at the same time (it uses deprecated mysql connection not pdo like Doctrine).
That said I have done the following test:
I have inserted a sleep(3); at my DefaultController. I requested that page and simultaneously requested a different one. See the two profilers below:
Page with sleep (called 1st):
Page without sleep (called 2nd).
Page 1 normal load time is 782ms
Page 2 normal load time is 108ms
As you can see Symfony's Http Firewall is taking all of the time of the second page to load.
My guess (might be stupid) is that 1st action holds the database connection and only until it has finished with it does it let it go for other requests to use it. And especially something having to do with Doctrine's use of PDO connection.
By the way I have already read help and articles like:
- What is the Symfony firewall doing that takes so long?
- Why is constructing PDO connection slow?
- https://www.drupal.org/node/1064342
P.S. I have tried using both app.php and app_dev.php in apache configs nothing changed. Sticked to app_dev.php so I can have the profiler. And local development using Symfony's build in server has the same result
You can not have 2 concurrent requests for the same open session in PHP. When you use a firewall, Symfony locks the user session and until you release it manually or the request is served.
To release the session lock use this:
$session->save();
Note there will be some drawbacks and iimplications. After you save the session, you will not be able to update it (change attributes) until the next request arrives.
Session management: https://symfony.com/doc/current/components/http_foundation/sessions.html
Session interface: http://api.symfony.com/4.0/Symfony/Component/HttpFoundation/Session/SessionInterface.html#method_save
Note 2. If you have multiple concurrent users with different sessions PHP will serve concurrently those requests.

symfony 3.4 FirewallListener Slow / Blocking

When i´m doing a request to a "huge" page with a lot of data to load, and make a second request to a "normal" content page, the normal page is blocked until the "huge" is loaded.
I activated the Profiler and recognized that the FirewallListener was the blocking element).
Profiler Screenshots (Loaded huge, switched tab - loaded normal)
Huge
Normal
While the "huge" page was loaded, i did a mysql php request on cli with some time measurements:
Connection took 9.9890232086182 ms
Query took 3.3938884735107 ms
So that is not blocking.
Any ideas on how to solve that?
Setup:
php-fpm7.2
nginx
symfony3.4
It is been blocked by the PHP Session.
You can't serve to pages that requires access to the same session id.
Although once you close/serve/release the session on the slow page, another page can be served on the same session. On the slow page just call Session::save() as soon as possible on your controller. This will release the session. Take into consideration that everything you do after saving the session will not be stored in the session.
The reason the firewall takes so long is that of debug is enabled.
In debug, the listeners are all wrapped with debugging listeners. All the information in the Firewall is being profiled and logged.
Try to run the same request with Symfony debug disabled.
We had a similar problem. When sending a couple of consecutive requests to the server in a short period, the server became very slow. I enabled the profiler bar, and a lot of time was spent by the ContextListener
The problem was that file server access on our server is very slow, and session information was stored on the file system, as is the default for symfony.
I configured my app to use the PdoSessionHandler, and the problem was gone.

How to keep a shell open across multiple ajax requests in PHP?

I need to use a shell across multiple ajax requests. Basically this means that the next request should be able to continue with the same shell where the other process left off.
The purpose is to communicate with daemons like FTP to open an FTP connection and log in and in the next request continue with that connection and be able to use it for uploads. But it's not limited to only the FTP daemon (as I know that FTP is supported in PHP).
It depends upon the system you want to design but in general, it could be done by maintaining request levels in session or in database, i.e. first check for login, if user is logged in then shell can allow more requests. You may need to define steps of communication for which requests are desired.

Why does apache not process multiple requests from the same browser simultaneously

I'm not quite sure how to phrase this question correctly, so I'll start with the scenario I encountered.
I have a bit of processing in my web app that takes longer than I'd like the user to wait to have control of the page again, so I decided to have it processed by an ajax request.
The problem is, even though I offloaded this request into an ajax request, it seems that apache won't process any further requests until the original processor heavy request is complete.
I originally wanted to know how I could get around this issue, but have since decided that it might be a bad idea in general.
However, I'm still curious if anyone knows why apache behaves this way, and what (if any) configuration directive controls it. My original thought was KeepAlive, but disabling that didn't seem to change the behavior.
I am running php through mod_php if that makes a difference.
I appreciate any help getting pointed in the right direction!
Are you using file-based sessions? PHP will lock session files for each request and maintain that lock until you do a session_write_close() or the script terminates/exits. The side effect of this is that all requests become serial, since they're all contending for the same single resource (the session file).
I am sure it's the session file. I have the same problem. I run a request that is long such as a PHPMyAdmin SQL insert which takes multiple minutes to process. While it is processing I try to open a new tab in the same browser and go to any page on my website and it will not go there until the original PHPMyAdmin request is done.
If I open an incognito window in Chrome which is the same browser it works fine. If I open the website in any other browser it is fine.
So it is probably the file based session which is the default for PHP.
Others have mentioned going to memcached. You could also save sessions in the database.
Before having to go to memcached you could do all the session based stuff at the beginning. Copy the session variable into a temporary variable so you can close it then close it. And then if you need to set a session value later open it and make the change and then close it quickly.
Can you point to evidence that it's apache? Unless your apache setup isn't optimal, most likely your page wait is something else, maybe you have set your ajax call to be non-async?

Categories