python-eel / Eel

A little Python library for making simple Electron-like HTML/JS GUI apps
MIT License
6.42k stars 586 forks source link

When user closes the window, the program can still be running in the background #610

Open nh916 opened 2 years ago

nh916 commented 2 years ago

Eel version 0.14.0

Describe the bug: When the user is running the app, decides to close the app window GUI, the user believes they have ended the program but the python program is still running in the background and the user has no idea

To Reproduce: Steps to reproduce the behavior:

  1. create an eel program with an infinite loop
  2. launch the app and watch GUI run and the python function in the back enter an infinite loop
  3. then close the app window
  4. the python program will still be running in the background forever unless the user knows and stops it manually

Expected behavior: I expect both the app GUI and the python program to close when I closed the window

Desktop:

Blauschirm commented 2 years ago

Stopping the Eel Server when clients disconnect isn't always wanted behaviour. You can implement the functionality yourself though by calling a python function that stops the server when the website unloads(closes). On JS side it would be:

window.addEventListener("beforeunload", () => { eel.close_python()} );

And in Python:

import sys

@eel.expose
def close_python(*args):
    sys.exit()
dstricks commented 2 years ago

Hey @nh916, thanks for the question!

I'll start by saying there are a lot of nuances when working with threads... without seeing an exact code example it's hard for me to make recommendations. That said, if you start up additional non-daemon threads and those are still running when the browser is closed, then yeah you're right, the Python application will continue running until those threads are finished.

As @Blauschirm mentioned, halting those threads isn't always wanted because they might be doing a critical bit of work such as saving a file, updating a database, or similar. Therefore, Eel doesn't try to brute force stop them.

You have at least three options here:

  1. If you're willing to have the additional threads just die off, set daemon=True on them and they'll be closed when the main thread is stopped (when the browser is closed)
  2. Similar to what @Blauschirm recommended, Eel provides a close_callback that can be passed to eel.start and do whatever you want to shut down those additional threads (including a brute force exit if you choose)
  3. Follow a pattern similar to what's documented on the Asynchronous Python section of the documentation in the README.md

Regarding recommendation 2 from above... I wouldn't necessarily recommend this, but this is what I mean:

def close(page, sockets_still_open):
    os._exit(0)

eel.start('index.html', close_callback=close)

Hope this helps!

Sniper199999 commented 1 year ago

Can anyone share a Demo for this behavior, I cannot get this to work.

tianaconn commented 1 year ago

This can be referenced at - https://github.com/python-eel/Eel/issues/259

Firstly remember to link the eel.js on HTML files can work. I am faced with this issue as well. Finally found this is the error from eel__init.py. If import sys or from sys import exit is missing in your .py files, this will happen. But I tried from sys import exit it still didn't work. I eventually changed eel\init__.py from line 373:

    if len(_websockets) == 0:
        exit()

to

    if len(_websockets) == 0:
        sys.exit()

and adding to your .py files:

import sys

then works.