remi icon indicating copy to clipboard operation
remi copied to clipboard

Cannot terminate Python process with SIGINT

Open kyselejsyrecek opened this issue 7 months ago • 3 comments

This:

    def serve_forever(self):
        # we could join on the threads, but join blocks all interrupts (including
        # ctrl+c, so just spin here
        # noinspection PyBroadException
        try:
            def sig_manager(sig, callstack):
                self.stop()
                self._log.info('*** signal %d received.' % sig)
                return signal.SIG_IGN
            prev_handler = signal.signal(signal.SIGINT, sig_manager)
        except Exception:
            # signal.pause() is missing for Windows; wait 1ms and loop instead
            pass
        except KeyboardInterrupt:
            pass

in remi/server.py is just... WTF? How am I supposed to end the app gracefully with interrupt signal if Remi is just another user interface (it has physical buttons)?

The remi package (__init__.py) even imports a special function for starting the server:

from .server import App, Server, start

But apparently there is absolutely no interface for stopping it. Why?

I've found this old bug report where a functional solution was proposed but the report was closed for no reason: https://github.com/rawpython/remi/issues/274#issuecomment-457251735

So, if one has an instance of such a MyApp, they can do this:

        my_app = MyApp()
        def interrupt_handler():
            my_app_instance.server.server_starter_instance._alive = False
            my_app_instance.server.server_starter_instance._sserver.shutdown()
            return signal.SIG_DFL
        remi.start(my_app, ...)
        signal.signal(signal.SIGINT, interrupt_handler)

or they have to implement such a handler into their MyApp.

kyselejsyrecek avatar Jun 04 '25 15:06 kyselejsyrecek

Hello @kyselejsyrecek ,

Please look at https://github.com/rawpython/remi/blob/master/examples/closeable_app.py for a simple way to stop the application.

Kind Regards, Davide

dddomodossola avatar Jun 04 '25 15:06 dddomodossola

Hello @dddomodossola,

this does not apply. The Python project is multi-threaded and Remi is just one of many instances running under the main thread. All libraries are expected to handle SIGINT and terminate gracefully in consequence. Well, Remi ignores the signal for the entire application, causing it to stay hanging forever.

kyselejsyrecek avatar Jun 04 '25 15:06 kyselejsyrecek

Ok, but you see, the SIGINT is handled and the server should stop correctly. I suppose you need to stop the App instances too. You can create a custom SIGINT handler and close all the instances as shown in the closeable_app example. Let me know if this could be a good solution.

dddomodossola avatar Jun 04 '25 15:06 dddomodossola