How to send multiple HTTP responses in time (Report server processing state) without sockets - node.js

I am sending file to my NodeJS Express based server by HTTP POST.
After image is received by server, server starts processing. It takes few seconds and there is few steps in processing (Transform image, OCR, saving, etc).
I want to keep user informed while he waiting for server to process image with some responses ("Transforming image...","Converting...","Finishing...").
So I need some way to send data to user before actual end of processing and final response HTTP status and data.
Is this possible just by HTTP responses or I need to implement something different?

It is not possible for http to send two responses, you can build another api which the user can hit and get the status of the last request made, once you give an order to process the request, you can send the response as processing and a unique id using which the user can check the status (2nd api), and once the user hits another api to know the status, you can give him the current status as completed or in progress.

Related

How to know a POST request was received

I have a structure where an application sends a POST request, the API handles the parameters and enters them into the database then another application that is supposed to run a function when the POST request was handled. The only issue I'm having is how can I make the 2nd application know when the request was handled other than running a GET request on a time interval?
Another explanation:
Client A: POSTs data
API: Handles data
Client B: GETs and displays data to user
How can I tell Client B when to do the GET request?
This is all in node.js and using express
What you need is to push data to clients when something happens server-side. This can be achieved by either server side events (which do exactly this), or websockets which create a bidirectional communication channel between server and client. Which one to choose? Check out this stack overflow post.

How NodeJs Server handle concurrent requests? (Questions about Database end)

These days, I need to write a serial number generator API. The logic is simple. Every time a http request is sent to the API, the API returns a continuous serial number. The simple pseudo code is as follows:
Read the last number saved in the database, defined as lastNumber
lastNumber plus 1, and return it to the client.
Then, I got questions about concurrency. If multiple requests are sent
to the Generator API at the same time, what will happen?
The questions I think about are as follows:
NodeJs is a single-thread language, and it only processes one request at a time. Under normal circumstances, the generator should generate 001, 002, 003... in sequence. When there are a large number of requests sent to API at the same time, will they all get the same last serial number from the database, thus returning a duplicate serial number? For example, several requests read lastNumber as 001 at the same time, so they all return 002.
After reading many articles, this one helps the most. How, in general, does Node.js handle 10,000 concurrent requests?
There is a diagram that explains nodeJs processing requests
Single request
user do an action
│
v
application start processing action
└──> make database request
└──> do nothing until request completes
request complete
└──> send result to user
Multiple requests
request A ──> make database request
request B ──> make database request
request C ──> make database request
database request complete ──> send response A
database request complete ──> send response B
database request complete ──> send response C
Here comes my other question. What counts as a complete DB request? The Request of the Generator API to the database is one read + one write. Read LastNumber, and Write LastNumber+1. Is the DB request complete when both actions are completed?
Because Node is a single thread, when the database is handling the requests, Node will not be idle. It will continue to process request B, request C. Then, How far will "make DB request" of request B go? Please refer to the diagram below. The numbers are the order in which the actions are completed in my imagination.
(1) request A ──> make database request ––>(4) DB handle requests (read 001) (write 002)
(2) request B ──> make database request ––>(??)Questions: the order of process? How far will it go, then stop and wait
(3) request C ──> make database request
(5) database request complete ──> send response A
database request complete ──> send response B
database request complete ──> send response C
When (4) is not completed, How far will "make DB request" go? Since the lastNumber in DB needs to be updated to 002, request B can successfully return 003.
I don't know whether Transaction mechanism is part of the answers to my questions.
The questions may not be clearly sorted out. If you need clarification, please feel free to raise it. I will try my best to elaborate. Thank you~

Sending a response after jobs have finished processing in Express

So, I have Express server that accepts a request. The request is web scraping that takes 3-4 minute to finish. I'm using Bull to queue the jobs and processing it as and when it is ready. The challenge is to send this results from processed jobs back as response. Is there any way I can achieve this? I'm running the app on heroku, but heroku has a request timeout of 30sec.
You don’t have to wait until the back end finished do the request identified who is requesting . Authenticate the user. Do a res.status(202).send({message:”text});
Even though the response was sended to the client you can keep processing and stuff
NOTE: Do not put a return keyword before res.status...
The HyperText Transfer Protocol (HTTP) 202 Accepted response status code indicates that the request has been accepted for processing, but the processing has not been completed; in fact, processing may not have started yet. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place.
202 is non-committal, meaning that there is no way for the HTTP to later send an asynchronous response indicating the outcome of processing the request. It is intended for cases where another process or server handles the request, or for batch processing.
You always need to send response immediately due to timeout. Since your process takes about 3-4 minutes, it is better to send a response immediately mentioning that the request was successfully received and will be processed.
Now, when the task is completed, you can use socket.io or web sockets to notify the client from the server side. You can also pass a response.
The client side also can check continuously if the job was completed on the server side, this is called polling and is required with older browsers which don't support web sockets. socket.io falls back to polling when browsers don't support web sockets.
Visit socket.io for more information and documentation.
Best approach to this problem is socket.io library. It can send data to client send whenever you want. It triggers a function on client side which receives the data. Socket.io supports different languages and it is really ease to use.
website link
Documentation Link
create a jobs table in a database or persistant storage like redis
save each job in the table upon request with a unique id
update status to running on starting the job
sent HTTP 202 - Accepted
At the client implement a polling script, At the server implement a job status route/api. The api accept a job id and queries the job table and respond with the status
When the job is finished update the job table with status completed, when the jon is errored updated the job table with status failed and maybe a description column to store the cause for error
This solution makes your system horizontaly scalable and distributed. It also prevents the consequences of unexpected connection drops. Polling interval depends on average job completion duration. I would recommend an average interval of 5 second
This can be even improved to store job completion progress in the jobs table so that the client can even display a progress bar
->Request time out occurs when your connection is idle, different servers implement in a different way so timeout time differs
1)The solution for this timeout problem would be to make your connections open(constant), that is the connection between client and servers should remain constant.
So for such scenarios use WebSockets, which ensures that after the initial request and response handshake between client and server the connection stays open.
there are many libraries to implement realtime connection.Eg Pubnub,socket.io. This is the same technology used for live streaming.
Node js can handle many concurrent connections and its lightweight too, won't use many resources too.

Architecture for multiple intervaled request with multiple async request in them

Imagine a situation where a user send a request to the server and then the server needs to address an outer API sending 10 request to that API, each request must be with a 1 second wait time between each of them. When each of this request is resolved and a response returned and parsed I need to send each of the response items to another outer API once each of the items is completely resolved and parsed a socket.io connection should emit the results back to the client so he won't have to wait for 10 seconds until all the requests are resolved.
How would you address this kind of situation?
Been trying to use the 'when' library, sending proxy request using 'request-promise' but still can't wrap my head around on how to construct this kind of thing.
Added a diagram:

How can I abort a request sent using wininet?

I have an MFC application in which I used to send a post request to the corresponding server.
It is an http request, for uploading a file.
But there is a requirement to abort the request sent. Like if the user is sending a large file and user should be able to cancel the request before it is completed.
I am using wininet apis,
HttpSendRequestEx, InternetWriteFile and HttpEndRequest for this.
but once the request is sent, I am not able to abort it in between unless the request is got completed or timed out.
Anyone please suggest an option for canceling a processing or sent request.
I have tried closing the request handles, but still the request not gets aborted.
Any one please help..
Thanks in Advance
From a client aspect, you can only abort/disconnect from the current operation by using the InternetCloseHandle routine.
This will instantly abort the request/operation from a client perspective, so the user can continue with another action.
But when the data has already been sent to the server, this will only result in not getting back a response!
As said by Igor, you cannot abort the processing at the server, as soon as the complete request (data) has been sent (at which point the client just waits to receive data from the server).
So you need to look at the point where you want to cancel 'sending' the request or revert the file addition at the server by sending a new 'delete' request from the client to the server, using the response of the first request (this response should contain information about the added file - like a key).

Resources