How do I handle really intensive server-side tasks, that can take multiple minutes? It’s a user-facing task, so the user can give me some data, and the server will then work in the backend.
I am fairly new to this, but I think my browser won’t "wait" for this long, if I am using async/await
? But then if I don’t use async await, I won’t know whether the task was completed successfully?
Or am I missing something here?
3
Answers
Using await / async will work as this will wait forever until a promise (request to backend) has been fulfilled. You could show some kind of loading graphic to the user which is how other websites handle lengthy tasks.
Depends how big the task is, but an example if the task is fairly small (eg 10 seconds) we could use a ‘loading’ state as the way to identify if we should display loading graphic:
Axios Minimal Example
The bigger the task, the more brittle is a solution that depends on a single HTTP request/response. Imagine that the connection breaks after the task has been 99% completed. The client would have to repeat the whole thing.
Instead, I suggest a pattern like the following that depends on several HTTP requests:
POST /starttask
to start the task and receives a "task ID" in the response.GET /task/<taskID>
and receive a progress notification (50% completed). This can be used to animate a "progress bar" on the UI.GET /taskresult/<taskID>
.GET /taskresult/<taskID>?page=1
and so on) until it has received and processed the entire result. This should not burden the server much, because it simply reads the task result from the database.POST /taskcleanup/<taskID>
.I think it would be bad to keep the connection open waiting for the response for couple of minutes.
Instead, I would recommend SignalR server side notifications (or equivalent) to notify front end about tasks updates.
Notification DTO would contain all needed information about the task.
Backend:
On front end you just need subscribe to notifications and add handlers for them.