Avoid timeouts on long angular $http queries - javascript

I'm facing an issue with an AngularJs app. My application needs to send a GET query to some python bottle server which will process a script for 3-4 minutes.
I'm actually using the $http.get method in angular but after a minute, I get a timeout if my python app hasn't answered yet. The python app continues processing but, because of the timeout, I won't be able to read the response in my promise function.
Is there any way to deal with this kind of queries avoiding both timeouts from browsers and angular app?

You can set custom timeout for your http request in the second parameter of http.get() method:
$http.get('request-path', {timeout: 300000});
This will set timeout to 300 seconds = 5 minutes.

Related

How do you handle a short webhook timeout? (Node.js)

I have set up the eSignatures API for our app and until recently it has been working perfectly. The part that is now broken is the webhook function. So when a document gets signed by one of our clients, it triggers our webhook cloud function that then updates our database (seems simple?).
The problem is that eSignatures have now updated their timeout to only 8 seconds, which means that my function does not have enough time to run and respond to their servers. It does however still run and update the database correctly, but as it takes longer than 8 seconds, the 200 response never reaches eSignatures and therefore they retry the endpoint every hour (for ~5/6 hours). I have put in a catch so that data is not duplicated when this happens, but ideally we don't want the retries to take place!
My question is basically, is there a way to send a 200 response at the beginning of the function to eSginatures, and then continue with the updates? Or is there another solution to handle this timeout? As if anything does fail in the function, I still want to return a 4xx to eSignatures and in this case we will want the retry?
You can't send a response from your Cloud Functions and then continue executing tasks. When the response is sent, the Function is stopped. See this link and this one
But even if you could, sending a response before ending the tasks that your Cloud Function prevents you from sending a 4XX response if they fail. Hence, eSginatures would never retry.
I don't think you can do much else aside from possibly optimizing your Cloud Function or increasing the eSignatures timeout, which I don't think is possible ATM.

Warning: No such label 'RESPONSE TIME' for console.timeEnd()

Situation:
I have a Node.js api that is called many times a second on a website. I am using console.time('RESPONSE TIME') and console.timeEnd('RESPONSE TIME') to measure how long the api is taking to respond to the client on to each request.
Inside of the api, I am using a Promise.all() to aggregate responses from 4 different api's and then return a final response based on what the 4 apis returned.
Issue:
Everything works as expected except for an occasional warning logged Warning: No such label 'RESPONSE TIME' for console.timeEnd(). Why is this and how do I properly avoid this?
I speculate that it's because Node is asynchronous and while one request may still be waiting for it's 4 api's to respond, another request will have finished and hit the console.timeEnd() ending both timers since they share the same name. But I can't find an answer anywhere.
Your speculation is correct, you should have a unique label name for every api call.
Assuming every request has a unique identifier stored in req.id you can use the following:
console.time(`RESPONSE TIME request ${req.id}`)
// await api call
console.timeEnd(`RESPONSE TIME request ${req.id}`)

What is $http timeout mean?

When using $http we can set the timeout for it and it will look something like this:
$http.get(url,{timeout: 5000}).success(function(data){});
What is that timeout mean? Is it mean the connection (data download) must be completed within the timeout period? Or it is mean the delay time to receive respond from the server? What would be the best general minimal timeout setting for mobile connection?
If the http request does not complete within the specified timeout time, then an error will be triggered.
So, this is kind of like saying the following to the $http.get() function:
I'd like you to fetch me this URL and get me the data
If you do that successfully, then call my .success() handler and give me the data.
If the request takes longer than 5000ms to finish, then rather than continue to wait, trigger a timeout error.
FYI, it looks to me like AngularJS has converted to using standard promise syntax, so you should probably be doing this:
$http.get(url,{timeout: 5000}).then(function(data){
// successfully received the data here
}, function(err) {
// some sort of error here (could be a timeout error)
});
What is that timeout mean? Is it mean the connection (data download) must be completed within the timeout period?
Yes. If not completed within that time period, it will return an error instead. This avoids waiting a long time for a request.
Or it is mean the delay time to receive respond from the server?
No, it is not a delay time.
What would be the best general minimal timeout setting for mobile connection?
This is hard to say without more specifics. Lots of different things might drive what you would set this to. Sometimes, there is no harm in letting the timeout be a fairly long value (say 120 seconds) in case the server or some mobile link happens to be particularly slow some day and you want to give it as much chance as possible to succeed in those circumstances. In other cases (depending upon the particular user interaction), the user is going to give up anyway if the response time is more than 5 seconds so there may be no value in waiting longer than that for a result the user will have already abandoned.
timeout – {number|Promise} – timeout in milliseconds, or promise that should abort the request when resolved.
Source
Timeout means "perform an action after X time", in JS anyway.

Google Pub/Sub How to set read timeout on Pull

I would like to set the read timeout of the pull request on a subscription. Right now the only options are to set returnImmediately=true or just wait until the pubsub returns, which seems to be 90 seconds if no messages is published.
I'm using the gcloud-node module to make calls to pubsub. It uses the request module under the hood to make the the gcloud api calls. I've updated my local copy of gcloud-node/lib/pubsub/subscription.js to set the request timeout to 30 seconds
this.request({
method: 'POST',
uri: ':pull',
timeout: 30000,
json: {
returnImmediately: !!options.returnImmediately,
maxMessages: options.maxResults
}
}
When I do this, the behavior I see is the connection will timeout on the client side after 30 seconds, but pubsub still has the request open. If I have two clients pulling on the subscription and one of them timeout after 30 seconds, then a message is published to the topic, it is a 50/50 chance that the remaining listening client will retrieve the message.
Is there a way to tell pubsub to timeout pull connections after a certain amount of time?
UPDATE:
I probably need to clarify my example a bit. I have two clients that connect at the same time and pull from the same subscription. The only difference between the two is that the first one is configured to timeout after 30 seconds. Since two clients are connected to the same subscription, pubsub will distribute the message load between the two of them. If I publish a message 45 seconds after both clients connect, there is a 50/50 chance that pubsub will deliver the message to the second client that has not timed out yet. If I send 10 messages instead of just one, the second client will receive a subset of the 10 messages. It looks like this is because my clients are in a long poll. If the client disconnects, the server has no idea and will try to send published messages on the response of the request that was made by the client that has timed out. From my tests, this is the behavior I've observed. What I would like to do is be able to send a timeout param in the pull request to tell subpub to send back a response after a 30000ms if no messages are published during that time. Reading over the API docs, this doesn't seem like an option.
Setting the request timeout as you have is the correct way to timeout the pull after 30 seconds. The existence of the canceled request might not be what is causing the other pull to not get the message immediately. If your second pull (that does not time out) manages to pull other messages that were published earlier, it won't necessarily wait for additional message that was published after the timeout to come in before completing. It only guarantees to not return more than maxMessages, not to return only once it has exactly maxMessages (if that many are available). Once your publish completes, some later pull will get the message, but there are no guarantees on exactly when that will occur.

how to update chat window with new messages

setInterval(function{
//send ajax request and update chat window
}, 1000)
is there any better way to update the chat with new messages? is this the right way to update the chat using setInterval?
There are two major options (or more said popular ways)
Pulling
First is pulling, this is what you are doing. Every x (milli)seconds you check if the server config has changed.
This is the html4 way (excluding flash etc, so html/js only). For php not the best way because you make for a sinle user a lot of connections per minute (in your example code at least 60 connections per second).
It is also recommended to wait before the response and then wait. If for example you request every 1 second for an update, but your response takes 2 seconds, you are hammering your server. See tymeJV answer for more info
Pushing
Next is pushing. This is more the HTML5 way. This is implemented by websockets. What is happining is the client is "listing" to a connection and waiting to be updated. When it is updated it will triger an event.
This is not great to implement in PHP because well you need a constanct connection, and your server will be overrun in no time because PHP can't push connections to the background (like Java can, if I am correct).
I made personally a small chat app and used pusher. It works perfectly. I only used the free version so don't know how expensive it is.
Pretty much yes, one minor tweak, rather than encapsulate an AJAX call inside an interval (this could result in pooling of unreturned requests if something goes bad on the server), you should throw a setTimeout into the AJAX callback to create a recursive call. Consider:
function callAjax() {
$.ajax(options).done(function() {
//do your response
setTimeout(callAjax, 2000);
});
}
callAjax();

Categories