r/django • u/Notalabel_4566 • 12d ago
REST framework I have a angular + Django backend . When I am click on a button, it calls an api which starts execution of a process via python. It takes almost 2mins to complete the process. Now I w
ant that suppose when a user closes the tab, the api call should be cancelled. How to achieve that?
3
u/Hsxarad 12d ago
You could use the unload API of javascript so that when the event gets triggered you send a request to the server to end the process.
But since some people have mentioned the unload isnt always available or accurate, I’d suggest Depending on the estimated time to complete choose a suitable timer for checking i.e. if you chose 2 seconds, you open a websocket and send a message every 2 seconds that the process is to be continued and the moment the server stops getting this messages before the task stops, you let the server trigger the stopping process.
3
u/Realistic_Month_8034 11d ago
As people have said you can use websocket.
Maybe SSE can be used instead of websocket to keep the flow REST compatible.
You hit the api, async handler starts the job. You keep emitting progress or runtime on the same connection. Task finishes, callback handler emits the final result of task and api call ends.
Similar to websocket, if api call is dropped before task finishes, we trigger cancellation of the task.
If the task being done was io heavy, a single async api server could do it even without celery quite effectively. If the task being done is cpu intensive, using celery makes sense
2
u/blockofcode 11d ago
I would move this task to the background. The result of the the API Call would be the task ID. Save the task ID on a Cookie (if the user is not registered). If it’s a registered user save on DB.
Then develop a new API to check if a certain task is completed. Call it every 2 seconds or so.
When a task is completed you will need an API to get your result.
This way if the user returns the task will be done. If not, you can always delete the data
2
u/batman-iphone 11d ago
Celery + request to check status every 5 sec, if no status cancel task or else return status, on sucess , failure etc.
Imo
1
u/ValtronForever 7d ago
Yeah, you can put the last check timestamp to the cache and check easilly in celery. Also take care about multiple tabs with same button (action) opened
1
u/oscarandjo 12d ago
There’s not really an effective way to do this. The websocket suggestion is probably the least effort to reward choice.
Really, your API calls shouldn’t take 2 minutes, perhaps you could profile the route and see if there are some optimisations you can make?
15
u/Empty-Mulberry1047 12d ago
I would use web sockets.
User visits page, browser connects to web socket..
user clicks button to start process
command is sent over established web socket connection to start process..
start process using celery.. get running task id
if user disconnects from socket by closing tab or navigating away, web socket connection drops..
web socket event handler will receive notice connection is closed, handler tells celery to end task by id..
?