I have Nginx 1.4.4 and PHP 5.5.6. I'm making long-polling requests. Problem is, that if I cancel the HTTP request sent via Ajax, requests are still processing (they don't stop). I tested it with the PHP mail() function at end of file, and mail is still coming the file didn't stop).
I'm worried, because I think that it might cause server crash because of the high load of unclosed requests. Yes, I tried ignore_user_abort(false);
but with no changes. Is possible that I should change something in Nginx?
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
The bad news is you are almost certainly not going to be able to solve you problem how you want to solve it. The FastCGI signal sent when a client closes a connection before receiving a request is FCGI_ABORT_REQUEST
A Web server aborts a FastCGI request when an HTTP client closes its transport connection while the FastCGI request is running on behalf of that client. The situation may seem unlikely; most FastCGI requests will have short response times, with the Web server providing output buffering if the client is slow. But the FastCGI application may be delayed communicating with another system, or performing a server push.
Unfortunately it looks like neither the original fast-cgi implementation nor PHP-FPM support the FCGI_ABORT_REQUEST signal, and so can't be interrupted.
The good news is there are better ways to solve this problem. Basically you should never have requests that take a long time to process. Instead if a request needs a long time to process you should:
In addition to those 3 basic things - if you're concerned about wasting system resources when a client is no longer interested in the results of a request you should add:
You don't say what your long running task is - let's pretend that it's to download a large image file from another server, manipulate that image, and then store it in S3. So the states for this task would be something like:
TASK_STATE_QUEUED
TASK_STATE_DOWNLOADING //Moves to next state when finished download
TASK_STATE_DOWNLOADED
TASK_STATE_PROCESSING //Moves to next state when processing finished
TASK_STATE_PROCESSED
TASK_STATE_UPLOADING_TO_S3 //Moves to next state when uploaded
TASK_STATE_FINISHED
So when the client sends the initial request, it gets back a taskID and then when it queries the state of that task, either:
or
i.e.
TASK_STATE_QUEUED => TASK_STATE_DOWNLOADING
TASK_STATE_DOWNLOADED => TASK_STATE_PROCESSING
TASK_STATE_PROCESSED => TASK_STATE_UPLOADING_TO_S3
So only requests that the client is interested in continue to be processed.
btw I'd strongly recommend using something that is designed to work performantly as a Queue for holding the queue of tasks (e.g. Rabbitmq, Redis or Gearman ) rather than just using MySQL or any database. Basically, SQL just isn't that great at acting as a queue and you would be better using the appropriate technology from the start, rather than using the wrong tech to start, and then having to swap it out in an emergency when your database becomes overloaded when it's trying to do hundreds of inserts, updates per second just to manage the tasks.
As a side benefit, by breaking long running process up into tasks, it becomes really easy to:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With