Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python graceful exit upon interrupt signal #39

Closed
lubocode opened this issue Oct 9, 2020 · 8 comments
Closed

Python graceful exit upon interrupt signal #39

lubocode opened this issue Oct 9, 2020 · 8 comments
Labels
enhancement New feature or request

Comments

@lubocode
Copy link
Contributor

lubocode commented Oct 9, 2020

Currently the Python script throws exceptions when interrupted through a SIGINT (ctrl + c) or SIGTERM.
To gracefully exit the script a signal handler needs to be introduced. This could look something like this:

from threading import Thread, Timer, Lock, enumerate, main_thread
import signal

def interruptHandler(signal, frame):
	print('Termination signal detected. Exiting gracefully.')
	threads = enumerate()
	print("Trying to join the following threads:")
	print(threads)
	for t in threads:
		if t != main_thread():
			if t is threading.Timer:
				t.cancel()
			else:
				t.join()
	sys.exit(0)

def main():
	# Listen for interrupt signal (e.g.: ctrl + c)
	signal.signal(signal.SIGINT, interruptHandler)
	signal.signal(signal.SIGTERM, interruptHandler)

Though after trying around a bit, the script continues to run even after successfully going through the join loop on my PC.
It also spawns a new Timer thread, which at least shows that the original Timer thread was successfully cancelled.
I think that either there is a thread that is not listed with enumerate() or sys.exit(0) is not working correctly, but I don't have enough experience with python threading to figure out what's really going on.

Resources:
Signal library
Threading library

@lubocode lubocode added the enhancement New feature or request label Oct 9, 2020
@gekigek99
Copy link
Member

ok this seems cool!

just to know:
this does not work at all?

# listen for interrupt signal and issue stopEmptyMinecraftServer(true) before exiting
atexit.register(stopEmptyMinecraftServer, forceExec=True)

because for me it seemed to do the job..

@lubocode
Copy link
Contributor Author

lubocode commented Oct 12, 2020

Well, pressing ctrl + c on Windows doesn't do anything and pressing it on Linux (two presses needed to actually stop the script) the following happens:

Copyright (C) 2019-2020 gekigek99
v6.6 (Python)
visit my github page: https://github.com/gekigek99
12-Oct-20 16:48:43 *** listening for new clients to connect...
^CTraceback (most recent call last):
  File "minecraft-vanilla-server-hibernation.py", line 534, in <module>
    main()
  File "minecraft-vanilla-server-hibernation.py", line 145, in main
    clientSocket, clientAddress = listener.accept()        #blocking
  File "/usr/lib/python3.8/socket.py", line 292, in accept
    fd, addr = self._accept()
KeyboardInterrupt
^CException ignored in: <module 'threading' from '/usr/lib/python3.8/threading.py'>
Traceback (most recent call last):
  File "/usr/lib/python3.8/threading.py", line 1388, in _shutdown
    lock.acquire()
KeyboardInterrupt:

As such I tried to intercept the KeybordInterrupt with the signal listener and since a simple sys.exit(0) didn't work, I tried consolidating all spawned threads back into the main thread before exiting. Upon exit the functions registered with atexit.register for execution should still be executed. Although, as it is, it's not quite finished and still doesn't properly exit.

@lubocode
Copy link
Contributor Author

lubocode commented Oct 13, 2020

Will test if mc server gets shutdown on Windows when closing console and in Linux after two times ctrl + c.
If not, this is a bug. If yes, then enhancement status stays.

@lubocode
Copy link
Contributor Author

facepalm os.Exit(0) needs to be written in Uppercase...

@gekigek99
Copy link
Member

facepalm os.Exit(0) needs to be written in Uppercase...

Wait... the uppercase thing is used in golang and I think it'correct to write sys.exit() in python

@gekigek99
Copy link
Member

gekigek99 commented Oct 15, 2020

@lubocode since python is deprecated i will now close the issue... unless we want to solve this last one

I can create a branch from commit c5804b6 and re-release version 9.12 with this bug corrected

@lubocode
Copy link
Contributor Author

facepalm os.Exit(0) needs to be written in Uppercase...

Wait... the uppercase thing is used in golang and I think it'correct to write sys.exit() in python

... Oops.

@lubocode since python is deprecated i will now close the issue... unless we want to solve this last one

I can create a branch from commit c5804b6 and re-release version 9.12 with this bug corrected

Well, no. It's not exactly nice interrupt handling, but this is also not a bug, as the server is correctly shutting down upon exit. On Windows ctrl+c might not work, but closing the cmd window, in which the python script got started, also shuts down the server.

@gekigek99
Copy link
Member

On Windows ctrl+c might not work, but closing the cmd window, in which the python script got started, also shuts down the server.

a okok fiuuu so now i'm in peace with myself. so i think I can move on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants