Apache wont serve while polling - php

I have Wamp setup on my windows 8.1 machine which I am using for development. My problem is Apache wont serve me pages from the specific web app I am working on in a reasonable time while I am running the script that is doing the polling. Here is the script and its back end implementation
window.fetch_messages = function () // I call this when my page is loaded
{
var last_message = $("div.message:last").attr('data-ai_id');
var project_id = getParameterByName('project-id'); // Another one of my helpers
$.ajax({
url:'project_messages',
type:'POST',
data:{ project_id:project_id, latest_message:last_message },
timeout:50000,
success:new_messages,
error:function(data){ console.log(data); setTimeout(fetch_messages(),50000); }
});
};
And the backend
do
{
$messages = $this->mentor_model->query_messages($this->project_id,$this->viewer, $this->last_message_id);
if($messages)
break;
usleep(25000);
}
while(empty($messages));
echo json_encode($messages);
exit;
This all works but I cant work properly if apache is not responding to my other request to go to another page or something in a reasonable time. I have other web apps on the machine and they will work fine while polling but the web app itself wont respond to other requests in reasonable time and this only happends when I'm on the page that uses this script. As a note I also made sure mysql was not giving the issues here by visiting another wapp(coining) on the localhost that uses mysql and it responds fine.
What's apache's deal ? is there some setting or something I have to change. It should be able to handle this fine since its just me testing.

This is more than less a resource handle problem. The all round use of sessions were being blocked because the script in question was not allowing session data use while it was running (because it was using the data).
A simple session_write_close() placed in the loop just before calling usleep()/sleep() on the script solved my problem.
Placing it anywhere after you have done using the session data should solve yours.

Related

PHP Long Running Script timeout

I am creating a page that executes a shell script on a remote server to scan a website and outputs the results on the screen. The output can sometimes take awhile to get depending on the size of the site being scanned. Currently the script works and does what it's supposed to but the problem is when I scan larger sites it stalls and on the platform the website is being hosted on has a timeout of 30 seconds that I cannot alter.
I am wondering what the best way to keep the connection alive whether it just be sending dots to the screen or maybe something else just to keep the connection alive.
Here is my script
$ssh = new Net_SSH2('hostname');
if (!$ssh->login('username', 'password')) {
exit('Login Failed');
}
$ansi = new File_ANSI();
$ssh->enablePTY();
$ssh->setTimeout(60);
$ssh->exec("./test.sh | awk 'NR >= 16 {print}'\n");
$ansi->appendString($ssh->read());
echo $ansi->getHistory();
Any help or guidance is deeply appreciated.
You should rather let the page load and e.g. run an AJAX request that will wait for a reply/listen on a port than trying to keep the connection alive.
So on the user's side, it would run an ajax request (javascript) to the php url, then on success you display the result.
$.ajax({
url: "/thescript.php":,
type: "POST",
datatype: "POST"
success: function(){
//do display stuff
}
});
Would probably add a reasonable timeout.
The timeout you are referring to is most likely a script execution time limit [very common on shared hosting]
And there is not much you can do about that sadly.
However what you can do is [if you have control over the server where the script is called from] is
send the request to the remote server [including a webhook callback url]
Have the script do it's thing
Have the script run the webhook to do the processing of the results
offcourse this also has implications on how the processing/displaying should be handled but i do not have enough information to go into specifics in this answer.
Do not attempt to execute long running scripts in a web page.
If you need a response from another system and you have SSH access then seperate the invocation of the task and the collection of the results into 2 seperate steps (see link above and the discussion it links to for some hints on how to do the invocation). Put a timed redirect on the first page to the second.

What is correct way to make Ajax call that sets a session/cookie in Magento?

I am new to Magento currently I am trying to make a regular Ajax call from my JS file. To a PHP file located in a root of my project same level as app folder. However when I execute the call ajax part works fine however I always get 500 response in my network console. If I try to call file directly like website.com/file.php it shows nothing but it should. Is there something in magento that is preventing me from doing this?
Also what is the best way to set a session and cookie in Magento, I did a small script locally that once pop up is closed it doesn't show it for the remainder of the session (and it works locally) but in Magento I can't get it.
Here is some of my code:
Ajax
// Create a session to not show pop-up
jQuery.ajax({
url: jQuery('#baseURL').val() + "/mailchimp_controls.php",
type: "post",
data: { "action": "session" },
success: function(data){
// Do something if necessary
}
});
PHP
// If Session set a session
if($_POST['action'] == "session"){
return "Session";
// Set value in session
$seen = true;
//Mage::getSingleton('core/session')->setShowMailChimp($seen);
}
I managed to solve this, I have create a Magento Module inside the APP/Core/Local
Where I was able to use MAGE to set sessions and cookies, if anyone is experiencing similar issues I would Google a tutorial on how to create a module inside (local) folder so that it is not overridden when you upgrade.

Web application is suspended (hanging up) while php curl_multi_exec is running [duplicate]

I have problem with two simultaneous AJAX requests running. I have a PHP script which is exporting data to XSLX. This operation take a lot of time, so I'm trying to show progress to the user. I'm using AJAX and database approach. Actually, I'm pretty sure it used to work but I can't figure out why, it's no longer working in any browser. Did something change in new browsers?
$(document).ready(function() {
$("#progressbar").progressbar();
$.ajax({
type: "POST",
url: "{$BASE_URL}/export/project/ajaxExport",
data: "type={$type}&progressUid={$progressUid}" // unique ID I'm using to track progress from database
}).done(function(data) {
$("#progressbar-box").hide();
clearInterval(progressInterval);
});
progressInterval = setInterval(function() {
$.ajax({
type: "POST",
url: "{$BASE_URL}/ajax/progressShow",
data: "statusId={$progressUid}" // the same uinque ID
}).done(function(data) {
data = jQuery.parseJSON(data);
$("#progressbar").progressbar({ value: parseInt(data.progress) });
if (data.title) { $("#progressbar-title").text(data.title); }
});
}, 500);
});
the progress is correctly updating in database
the JS timer is trying to get the progress, I can see it in console, but all these request are loading the whole duration of the first script, as soon as the script ends, these ajax progress calls are loaded
So, why is the second AJAX call waiting for the first one to finish?
Sounds like a session blocking issue
By default PHP writes its session data to a file. When you initiate a session with session_start() it opens the file for writing and locks it to prevent concurrent edits. That means that for each request going through a PHP script using a session has to wait for the first session to be done with the file.
The way to fix this is to change PHP sessions to not use files or to close your session write like so:
<?php
session_start(); // starting the session
$_SESSION['foo'] = 'bar'; // Write data to the session if you want to
session_write_close(); // close the session file and release the lock
echo $_SESSION['foo']; // You can still read from the session.
After a bit of hair-pulling, I found one other way that these non-parallel AJAX requests can happen, totally independent of PHP session-handling... So I'm posting it here just for anyone getting here through Google with the same problem.
XDebug can cause this, and I wouldn't be surprised if Zend Debugger could too.
In my case, I had:
XDebug installed on my local LAMP stack
xdebug.remote_autostart enabled
My IDE accepting inbound debugger-connections, even though no breakpoints were active
This caused all my AJAX tests to run sequentially, no matter what. In retrospect it makes a lot of sense (from the standpoint of debugging things) to force sequential processing, but I simply hadn't noticed that my IDE was still interacting behind-the-scenes.
After telling the IDE to stop listening entirely, parallel runs resumed and I was able to reproduce the race-condition I had been looking for.
Be aware, that session_write_close()(answer of chrislondon) may not resolve the problem if you have enabled output buffering (default in PHP 7+). You have to set output_buffering = Off in php.ini, otherwise session won't be closed correctly.
When working with APIs, you sometimes need to issue multiple AJAX requests to different endpoints. Instead of waiting for one request to complete before issuing the next, you can speed things up with jQuery by requesting the data in parallel, by using jQuery's $.when() function:
Run multiple AJAX requests in parallel
a.php generates a main HTML page that contains two simultaneous AJAX calls to b.php and c.php. In order for b.php and c.php to share session variables, the session variables must exist BEFORE the first AJAX call. Provided this is true, a.php and b.php can change the value of the session variables and see each other's values. Therefore, create the session variables with a.php while generating the HTML page. At least that's how it works with Rogers shared web hosting.
You could also set
async: true,

Polling Apache server not responding

The apache server I am using to develop my system will not respond to request while the scripts that control the polling of messages is being run. This only happends on a domain level meaning that I can send an http request to any other apps hosted localy and get a response. When I do eventually get a response from this its about a minute later.
Here is the Js
window.fetch_messages = function ()
{
var last_message = $("div.message:last").attr('data-ai_id');
var last_message_status = $("p.message_status:last").text();
var project_id = getParameterByName('project-id');
$.ajax({
url:'/project_messages',
type:'POST',
data:{ project_id:project_id, latest_message:last_message, status:last_message_status },
timeout:50000,
async: true,
success:new_messages, // This upon completion also resends the request
error:function(data){ console.log(data); setTimeout(fetch_messages(),50000); }
});
}; // When On the page that uses this I call this function to start polling
Here is the server side code
do
{
// Check for status change
$status_change = $this->mentor_model->query_status($this->project_id, $this->last_message_id, $this->last_message_status, $_SESSION['user']);
// Check for new messages
$messages = $this->mentor_model->query_messages($this->project_id, $this->last_message_id);
// If there is a status update or new message.
if($messages || $status_change)
break;
usleep(1000000);
}
while(empty($messages) && empty($status_change));
echo json_encode(array("messages"=>$messages, "status"=>$status_change));
exit;
While this action is being run The server takes a long time to handle any request weather it be a GET, POST or another AJax request. Iv also tried changing both code sets to no avail as long as its long polling, the server will take a long time to handle.
Do I have this wrong or is there some apache setting I'm suppose to change. Using xamp on windows 8.1 also tried wamp with no change
Thanks to steven for this. Ansewer taken straight from the source of php manual page
for session_write_close();
You can have interesting fun debugging anything with sleep() in it if
you have a session still active. For example, a page that makes an
ajax request, where the ajax request polls a server-side event (and
may not return immediately).
If the ajax function doesn't do session_write_close(), then your outer
page will appear to hang, and opening other pages in new tabs will
also stall.

Set $_SESSION in ajax request

I have this Jquery Ajax function to login in a web page.
url="<?php echo Yii::app()->createUrl("security/login") ?>"
$.ajax({
type:"POST",
url:url,
data:{},
success: function (jsonResponse) {
var json=JSON.parse(jsonResponse);
if(json.result == "SUCCESS")
{
<?php $_SESSION['LOGGED_USER']="USER"; ?>
}
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(errorThrown);
}
});
And in my views layout I have this
session_start();
if( isset($_SESSION['LOGGED_USER']) )
{
print_r("LOGGED");
}
else
{
print_r("NOT LOGGED");
}
When I enter for the first time to the page It prints "NOT LOGGED" but it seems that it sets automatically the session so that when I reload the page It prints "LOGGED".
How can I set my session correctly in my ajax request?
Thank you very much :)
It seems a lot of people are confused about client vs server when it comes to Ajax. Let me see if i can clear that up:
Your JS runs in the browser (client). PHP runs on the server. The two are different languages that run on entirely different machines; they don't share the same variables or anything. They do not talk directly to each other, or really even know anything about each other. Their sole means of communication is via HTTP requests. (Well, there's WebSockets too...but that's a bit advanced yet.)
JS and PHP typically do not even run at the same time. Depending on your setup and where this script lives, one of two things is happening, and in this case, neither one is what you want.
The JS is in a file of some type the server doesn't feed to PHP. The PHP code is still in the file when the browser sees it -- and being invalid JS, causes a syntax error when you try to run it. Probably before you even get to do the Ajax post.
The JS is in a file of some type the server does feed to PHP. The PHP interpreter dutifully goes through the file, finds all the PHP code in it, and parses and runs it. The PHP code in it runs on the server, possibly before the page is even sent to the browser. (And since PHP doesn't speak JS, and doesn't even care if what it generates is valid HTML or JS...any non-PHP code in the page is irrelevant.) Anyway, by the time the browser runs your script above, it looks like this:
...
success: function (jsonResponse) {
var json=JSON.parse(jsonResponse);
if(json.result == "SUCCESS")
{
}
},
...
because PHP has already gone through the file and interpreted the bit about setting $_SESSION['LOGGED_USER']. If the user has an active session at all, logged in or not, that LOGGED_USER variable is set the second his browser requests that page.
The PHP script that's handling requests for security/login needs to set the session variable. Your JS won't be able to do it, as the session data is entirely server-side, and you can't let the browser just up and tell the server to run arbitrary PHP code without opening up a massive security hole. (Picture what could happen if the browser could say "hey, PHP, run this". All i'd have to do is pop up a JS console, see how you're doing it...and at the very least, i could write a line of JS in the console to set that variable whether i'm logged in or not.)
Or, if you really wanted, you could create another page that the JS posts to, that sets the session data. That seems a waste, though...and it might be quite difficult to do securely. (If PHP doesn't already know you're logged in, you'd have to re-authenticate and all that.) I wouldn't consider it unless for some reason security/login can't be modified.

Categories