PHP Thread telling to JavaScript that will sleep - javascript

The title is a little confuse, but my problem is:
Javascript do an AJAX Request to the PHP Controller. In the PHP Controller a Thread is created and started. The code is:
public function run() {
while(true) {
//Do Something...
//Know I want to tell Javascript that I have done the thing and I'm going to sleep.
sleep(10000);
}
}
So the JavaScript code is:
$.ajax({
type: 'POST',
url: "controllers/DatabaseController/",
data: dataObject,
success: function(response) {
//Do Something after the Thread Result
}
});
I am thinking that this problem it's impossible... Because the Thread runs and sleep after a time set by the client. And when the Thread runs, the client side need to see the results of the Thread.
How can I do this? The Javascript need to be in a loop like the PHP Thread?
The situation is:
- Thread do polling of the equipments status and after that the javascript change the icons status (green or red) of the equipments.

What you can do is:
Create two controller methods: One to start the thread the other one to check the status of it.
You make your ajax request to start the thread. Once the thread is started, you return a response, with a success/error message.
If the thread was started successfully, you will then make a second ajax request periodically to check the status of the thread.
You may also, in the first call, return the expected time the thread will sleep so you can adjust the time which the second ajax request will be made.
Edit (trying to clarify):
Let's say that your thread will check how much fuel the machine has. That thread will query the machine and will save that into a database.
The second method in the controller will query the database and fetch the results saved by the thread.
Example:
Controller:
class Controller
{
public function startThread()
{
// start thread
// return
}
public function checkStatus()
{
// query database for status
// return results
}
public function thread()
{
// check for machines status
// save the results into database
}
}
Javascript:
$.ajax({
type: 'POST',
url: "controller/startThread/",
data: dataObject,
success: function(response) {
// if success
setTimeout(function() {
$.ajax({
type: 'POST',
url: "controller/checkStatus/",
data: dataObject,
success: function(response) {
// your result will be here
})
}, 10000)
}
});

Solution:
I used the javascript function setInterval with the time that user set, who runs a function that do an ajax request to the php controller.
The Controller create a thread that do the polling of the equipments and die.

Related

If api server is down, what is the best practice to alerting users that the server is currently unavailable clientside?

I have a website that basically makes API calls and displays the data in a table; the API is on a different server from the website.
If the API server is down what is the best way to alert the user client-side (JavaScript) that the server is unavailable?
Could/Should I put the alert in the API call error handling (See code for example)? What is the best practice for this type of situation.
function apiCall(query, product){
var p = product;
var urlr='https://myFakeAPIUrl/api/'+query+'/'+ product;
$.ajax({
contentType: 'application/json',
crossDomain: true,
url: urlr,
type: "GET",
success: function (result){
alert("Yay, the API server is up.");
},
error: function(error){
console.log(error);
alert("Sorry, the server is down.");
}
});
}
var productData = apiCall("Produce", "112233");
I would ask myself what a user would like to see in this situation.
What I always do is putting a timeout on the Ajax request, whenever that timeout of e.g. 9999ms runs out, the user should get notified (with a toast, a heading, etc..) that something went wrong and that they should try it again later.

Ajax call to wait for listener script to complete and notify user

I have a program that will let the user submit a test case from a webpage (main.php), the webpage will send an ajax request to insert a row in MySQL with user data (insert.php) with done=0. I then have a listener script (testexec.php) that runs every minute on a crontab to process/run (ssh into each server and run the test on the server) the test cases on each server and update the row to done=1 after the test is completed.
My ajax call will finish right away after the insert of the row is complete and will tell the user to wait.
I want to be able to let the user know when the listener script is finished with their test case and display the result back the page.
Here is my AJAX call:
main.php
//POST the data to insert.php
$.ajax({
url:"insert.php",
type: "POST",
data: {
gateway: $("#gateway").val(),
option: $('input[type=radio]:checked').val()
},
dataType: "text",
success:function(result){
$('#div0').html("Your test is being processed, please wait..");
//clearInterval(interval);
console.log(result);
alert('Test case submitted!');
}
});
return true;
}
});
Return the value of the 'responseText' value of the AJAX request. That way it will be synchronous.
//POST the data to insert.php
return $.ajax({
url:"insert.php",
type: "POST",
data: {
gateway: $("#gateway").val(),
option: $('input[type=radio]:checked').val()
},
dataType: "text"
}).responseText
You either set another ajax call on a timed interval to poll your server every few seconds and have the server return the result once its ready and clear the interval on the ajax call as part of the success function, or you create an event listener / websocket connection to the server and flush server output once it's available
Or, you incorporate the running of the test script into your php ajax handler script, increase the timeout on the ajax call if necessary and dont return any output until the test script finishes

HttpRequest not to timeout on a lengthy request

I have the following Ajax call
function exampleAjax() {
$('#loadingImage').show();
var id = GetId();
$.ajax({
url: "../Controller/MyRequest?id=" + id,
type: "GET",
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function (result) {
if (result.success === true) {
// Show Dialog Success
}
else {
// Show Dialog Failure
}
},
async: true,
processData: false
});
}
which calls below controller's method.
public async Task<JsonResult> MyRequest(string teamId)
{
bool success = false;
try
{
HttpResponseMessage response = await client.GetAsync(fullUriEndpoint)
if (!response.IsSuccessStatusCode)
throw new Exception(response.ReasonPhrase);
else
success = true;
return Json(new
{
success = success,
}, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json(new
{
success = success,
}, JsonRequestBehavior.AllowGet);
}
}
Because the request takes few minutes to process (this is totally fine, server needs to do a some processing that could take up to 5 minutes or more) then the client send back an exception although the task is still executed in the backend.
Is there a way I can manage this scenario without doing a fire and forget? I want to wait for the execution of this request until it gets completed.
As an option you may build a kind of polling process:
Client sends a request for "long operation".
Server starts the operation, gives it some id.
And immediately responds to the client that the operation has been started.
Then server listens for an API like GET /api/operation/:id to respond a status of given operation (done or in progress).
Client gets this pre-answer from (3) and run a timer, he requests the API from (4) every let's say 500ms until the operation is done or until N attempts are done.
Another option would be to provide bi-directional communication between server and client using WebSockets.
Probably your best bet would be to use SignalR. So ignoring that you should't run long running processes on asp.net.. I would recommend using something that does what you need in a different and easier way. SignalR abstracts Ajax/WebSockets so all you have to do is make calls either way (client to server or server to client).
Client to server (javascript):
$.connection.myHub.StartProcess()
Server
public class MyHub : Hub
{
public void StartProcess()
{
// DO WORK
// Call Client!
Clients().Client(id).ProcessFinished()
}
}
Client (Javascript)
$.connection.myHub.ProcessFinished = function(){
console.log('Long process finished!');
}

How does Rx really work on web (client side)

I have gone through the introduction part at Rx CodePlex page. I have watched the video of the guy with CascadiaJS. I have discovered how the RxJS library is used. I have a question about how is it going to help me with my existing Ajax application and what do I have to change on server side as well as client-side to make the most of RxJS.
Scenario
I have a REST service written using ASP.NET Web API. The service currently has one method, it takes an array of coordinates and return another array of coordinates. So the call is very simple, it goes like this.
$.ajax({
url: "http://www.myservice.com/service1/",
type: "POST",
data: JSON.stringify(params),
contentType: "application/json;charset=utf-8",
success: handle_success,
error: handle_failure,
OPTIONS: null,
});
Now the above call simply calls a REST service and takes appropriate action on how the results come out.
With Rx, I heard the mantra of "Push" instead of Pull. How are we going to fit "Push" into the sample above ? Am I going to change my REST service to be a Listening TCP Socket which my webpage will stay connected (or make a Keep-Alive connection) and new values will be "Pushed". Or this would just be a service call as above, but the success/error will just be "channeled" through Observable and once the call is finished, the job of that Observable is finished ?
Even without worrying about changing your server to push to the client, RxJs can help you compose your asynchronous actions on the client.
For example, if you model your ajax call as an observable:
// each time you subscribe to service, it will execute the ajax call and send back the result
var service = Rx.Observable.defer(function () {
return $.ajax({
url: "http://www.myservice.com/service1/",
type: "POST",
data: JSON.stringify(params),
contentType: "application/json;charset=utf-8"
});
});
// Now fun with Rx
// just call the service like in your OP example:
service.subscribe(handle_success, handle_failure);
// poll the service every 5 seconds
var pollInterval = Rx.Observable.empty().delay(5000);
service
.concat(pollInterval)
.repeat()
.subscribe(success, failure);
// run the service whenever user clicks Refresh
$('#refresh')
.onAsObservable('click')
.flatMap(function () { return service; })
.subscribe(success, failure);
// same as above, but ignore it when user clicks too fast (e.g. faster than 1 second)
$("#refresh")
.onAsObservable('click')
.debounce(1000)
.flatMap(function () { return service; })
.subscribe(success, failure);

javascript: handling client side initiated objects that the server hasn't assigned an id to

I'm developing a javascript application and I'm trying to make server side syncing as automagic and unobtrusive as possible
The problem I'm facing is that when creating an object client side I can immediately send the create ajax request and while I'm waiting for it to return add the object to the ui where necessary
However since the object has no id until the server responds I can't perform any update or destroy actions on it until the server responds and updates its id
What is the best way of dealing with this problem?
Some code if it helps:
create_object = function() {
return {
save: function() {
if (this.isNew()) {
this.create();
} else {
this.update();
}
},
isNew: function() {
return (this.id === undefined || this.id === null);
},
update: function () {
$.ajax({
url: '/update_object/'+this.id+'.json',
type: 'post',
dataType: 'json',
data: this
});
},
create: function () {
var object = this;
$.ajax({
url: '/create_object',
type: 'post',
dataType: 'json',
data: this,
success: function(data) {
object.id = data.id;
}
});
},
destory: function () {
$.ajax({
url: '/destroy_object/'+this.id+'.json',
type: 'get',
dataType: 'json'
});
}
};
};
var object = create_object();
object.message = "Foo!";
object.save();
// this will create a new object until object.save has responded
object.message = "Bar!";
object.save();
// this wont work until object.save has responded
object.destroy();
This is not really a problem. AJAX is asynchronous by nature (Asynchronous Javascript and XML). You will have to wait until you get a response from the server to update your UI.
If you must update the UI immediately, you can create an element with a placeholder ID that you can then update with the actual ID once the server responds.
UPDATE
This is in response to your comment. Webapps are not purely client-side applications. They fit into the client-server paradigm. You can try using a synchronous post, but this has the side-effect of tying up the browser until the server responds (this is due to the fact that Javascript is single-threaded).
That being said, the response from the server should be pretty quick unless your network is slow or if whatever post your sending to the server results in some computationally-intensive operation.
Going by the placeholder route will (as you have realized) result in all sorts of new problems that you have to deal with. You have to ensure that they are unique. Now what if they perform some operation on the client-side element before the server responds with an id? The server won't know what the placeholder id means. There are ways around this (queuing requests is one way), but it will make your code a whole lot more complicated. I don't think the tradeoff is worth it just to make the UI update faster.
An option is to provide some visual feedback to the user that the app is "working" (i.e., while you are waiting for a response from the server). A spinner, for example.
As far as stacking the AJAX requests, that is one approach that you can take using the jQuery message-queuing plugin.

Categories

Resources