Johan Vergeer
Johan Vergeer

Reputation: 5578

Kill Django process from browser

Within a Django view I call a function for uploading and importing an excel file.

def import_log(request):
    report = ""

    if request.method == "POST":
        file_object = request.FILES
        sheet_name = request.POST["sheet_name"]

        if len(file_object):
            file_object = file_object["file_object"]

        if len(file_object):
            process_import()

            context = {
                "report": report
            }

            return render(request, "import_log.html", context)

        else:
            return import_upload_view(request, error="No file uploaded")

When I try to stop the page by clicking "Stop loading this page" or by closing the browser the import process does not stop.

These import files are pretty big so I would like to be able to kill the process from the browser when needed.

How would I be able to do this?

Upvotes: 1

Views: 943

Answers (2)

LearnerEarner
LearnerEarner

Reputation: 1020

The only time Django/server would know about the 'aborted connection' is when it tries to send the response back. To understand this you can write a dummy view and sleep for may be 10 seconds in that view; call it from browser and stop it as fast you can; wait to see what Django does. If you are running Django Dev server it should be clear for you that Django does behave normally and sends the response but a 500 error happens because of aborted connection and then a try happens to send this 500 error to client which of course obviously fails too.

So, it is not possible to stop the view process in the middle.

But, you can change the way you approach this problem probably by first sending the request to your view then spin off a new process to do the "pretty big" import process; register the process by using some unique ID and current timestamp in some persistent data store (probably in a database); return HTTP status code 202(Accepted) with the registered ID to end the view.

In the spun process, have multihreading. One thread continuously polls the database to check delta between current time and the one in database. If the difference exceeds the threshold you decide (say 10 seconds) this whole process should kill itself.

From browser keep hitting an API (another Django view) using AJAX to update the timestamp in database for the particular record whose ID is the ID that you got in 202 response.

The idea is to keep let know the server that client is still available and if for some reason you don't see any ping from client, you would treat it as the case of browser close or navigate away from page and so stop working on the process spun off.

This approach may get tricky if you are single page application.

Upvotes: 0

Sayse
Sayse

Reputation: 43330

Put simply, you can't.

The internet works by sending requests to a server and then waiting for a response, it doesn't pertain an open connection to a process, thats the server's job to handle its own processes.

The browser is essentially nothing more than your computers monitor, displaying the information sent to it - so you could turn your monitor off or pull the plug as much as you'd like, its not going to stop your computer from running

Upvotes: 6

Related Questions