My problem is this:
I have a React Native app that requests data to the backend.
If backend takes longer than x seconds, the app aborts the request (made with fetch()) and tries to make another one.
That abortion was hastily, because the backend was just taking a longer time to process it.
The backend is made idempotent so new requests don't actually matter.
The backend finished processing the initial request, and now it wants to return the value, but that request was aborted by the client.
How should I deal with this?
I can't just abandon the abortion logic because it's not my app, but I can make simple fixes and improve logic on it. Also, I can do whatever it takes in the backend.
I've solved it by saving the express.Response objects alongside it's requests. Whenever a new, duplicate, request arrives I just replace the response object in an array, so that I always have a way to respond the app.
Related
I'm adding third party logging to my nodejs app, the API has an ingestion endpoint I need to call with logging information.
The problem is that this request takes time, if I await all the logging requests it will add significant time to function executions.
My thinking was to do a 'fire and forget' approach however given NextJS will cancel all executing processes this may occasionally fail. I also found logging may arrive in a different order than sent (though this can be mediated with a timestamp).
What I'd love to do is fire off the log and ensure the request has been sent without waiting on the response from the server - is this possible?
I'm thinking to add a 1ms wait after each log since an initial http request with a small payload isn't going to take that long to send but wanted to know are their any best practices for handling these sorts of scenarios?
Objective
I need to show a big table of data in my React web app frontend.
My backend is an Express server with a GraphQL layer and a few "normal" endpoints.
My server gets data from various sources, including an external API, which is the data source for my current task.
My server has a database that I can use freely. I cannot directly access the external API from my front end.
The data all comes from the external API I mentioned. In fact, it comes from multiple similar calls to the same endpoint with many different IDs. Each of those individual calls takes a while to return but doesn't risk timing out.
Current Solution
My naive implementation: I do one GraphQL query in which the resolver does all the API calls to the external service in parallel. It waits on them all to complete using Promise.all(). It then returns a big array containing all the data I need to my server. My server then returns that data to me.
Problem With Current Solution
Unfortunately, this sometimes leaves my frontend hanging for too long and it times out (takes longer than 2 minutes).
Proposed Solution
Is there a better way than manually implementing long polling in GraphQL?
This is my main plan for a solution at the moment:
Frontend sends a request to my server
Server returns a 200 and starts hitting the external API, and sets a flag in the database
Server stores the result of each API call in the database as it completes
Meanwhile, the frontend shows a loading screen and keeps making the same GraphQL query for an entity like MyBigTableData which will tell me how many of the external API calls have returned
When they've all returned, the next time I ask for MyBigTableData, the server will send back all the data.
Question
Is there a better alternative to GraphQL long polling on an Express server for this large request that I have to do?
An alternative that comes to mind is to not use GraphQL and instead use a standard HTTP endpoint, but I'm not sure that really makes much difference.
I also see that HTTP/2 has multiplexing which could be relevant. My server currently runs HTTP/1.1 and upgrading is something of an unknown to me.
I see here that Keep-Alive, which sounds like it could be relevant, is unusable in Safari which is bad as many of my users use Safari to access the frontend.
I can't use WebSockets because of technical restraints. I don't want to set a ridiculously long timeout on my client either (and I'm not sure if it's possible)
I discovered that GraphQL has polling built in https://www.apollographql.com/docs/react/data/queries/#polling
In the end, I made a REST polling system.
I'm working on a React/Node program. Somewhere in the program, I want to send a request to back-end using Axios, then while the back-end function is processing the request, I want to get step by step responses to update the front-end by showing some notifications.
I could do this by sending multiple requests and waiting for each response. But the problem is that the first process in each step is identically the same in all steps and it will create some performance issues.
My question is:
Is there any way to send a single request to API, then on the back-end side, return the response in multiple steps while it's processing? Meanwhile on the front-end, get the updates from back-end and update the notifications on it?
Thank you very much
Sorry bro, I'm afraid that you can't do this with using HTTP alone since the connection is ended with a single response for a single request. You need to do this with multiple HTTP call with Axios.
Otherwise, you could use WebSocket.
Their are cool Module socket.io with planty examples and documentations.
check this out,
https://www.npmjs.com/package/socket.io
I have a process in the back-end which will take take on average 30 to 90 seconds to complete.
Is it better to have a font-end react app make ONE API call and wait for back-end to complete and process and return the data. Or is it better to have the front-end make multiple calls, lets say every 2 seconds to check if the process and complete and get back the result?
Both are valid approaches. You could also report status changes with websocket so there's no need for polling.
If you do want to go the polling route, the general recommendation is to:
Return 202 accepted from your long-running process endpoint.
Also return a Link header with a url to where the status of the process can be read.
The client can then follow that client and ping it every x seconds.
I think it's not good to make a single API call and wait for 30-90 seconds to get a response. Instead send a response immediately mentioning that the request is successful and would be processed.
Now you can use web sockets or library like socket.io so that the server can communicate directly to the client once the requested processing is complete.
The multiple API calls to check if server is done or server has any new message is called polling and is not much efficient but it is still required in old browsers which don't support web sockets. Socket.io support s polling automatically in old browsers.
But, yes if you want you can do multiple calls to check if server is done processing, but I would prefer server to communicate back to the client , it is better.
Best way to respond restfully to a time consuming calculation (Node.js with Express)
I'm building a REST API using Node.js with Express.
Now I have to design the response to a time consuming calculation on the server side to a http request witch is ending up in a zip file with a few megabytes.
The calculation is done in a few seconds at the moment. But perhaps, if data grows up, it can take minutes sometime. So I think it's not the best way to wait in Express till data is ready and then res.sendfile() it back to the client. But what is the best solution?
Should I implement a delayed response with long polling? Like http-delayed-response
What I don't like here is that I immediately have to report HTTP 202. If the generation of the ZIP file fails, I have to deal with this in the response and cannot report it via HTTP status code. Also I cannot respond the file directly - as far as I know.
Or something with job ids and states to each job? Like express-delayed-response
In this way my API is not stateless anymore and I have to build a status handler.
Are there better and more established solutions to this problem?