Merge pull request #113 from cooperlees/main

Handle SIGTERM exits Cleanly too
Kaveen Kumarasinghe 2 years ago committed by GitHub
commit 8c2f5f62aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,5 +1,6 @@
import os import os
import asyncio import asyncio
import signal
import sys import sys
import threading import threading
import traceback import traceback
@ -29,6 +30,8 @@ from models.openai_model import Model
__version__ = "8.3.5" __version__ = "8.3.5"
PID_FILE = Path("bot.pid")
PROCESS = None
if sys.platform == "win32": if sys.platform == "win32":
separator = "\\" separator = "\\"
@ -173,22 +176,53 @@ async def main():
await bot.start(os.getenv("DISCORD_TOKEN")) await bot.start(os.getenv("DISCORD_TOKEN"))
def check_process_file(pid_file: Path) -> bool:
"""Check the pid file exists and if the Process ID is actually running"""
if not pid_file.exists():
return False
if system() == "Linux":
with pid_file.open("r") as pfp:
try:
proc_pid_path = Path("/proc") / "{int(pfp.read().strip())}"
print("Checking if PID proc path {proc_pid_path} exists")
except ValueError:
# We don't have a valid int in the PID File^M
pid_file.unlink()
return False
return proc_pid_path.exists()
return True
def cleanup_pid_file(signum, frame):
# Kill all threads
if PROCESS:
print("Killing all subprocesses")
PROCESS.terminate()
print("Killed all subprocesses")
# Always cleanup PID File if it exists
if PID_FILE.exists():
print(f"Removing PID file {PID_FILE}", flush=True)
PID_FILE.unlink()
# Run the bot with a token taken from an environment file. # Run the bot with a token taken from an environment file.
def init(): def init():
PID_FILE = "bot.pid" global PROCESS
process = None # Handle SIGTERM cleanly - Docker sends this ...
if os.path.exists(PID_FILE): signal.signal(signal.SIGTERM, cleanup_pid_file)
if check_process_file(PID_FILE):
print("Process ID file already exists") print("Process ID file already exists")
sys.exit(1) sys.exit(1)
else: else:
with open(PID_FILE, "w") as f: with PID_FILE.open("w") as f:
f.write(str(os.getpid())) f.write(str(os.getpid()))
print("" "Wrote PID to f" "ile the file " + PID_FILE) print(f"Wrote PID to file {PID_FILE}")
f.close() f.close()
try: try:
if EnvService.get_health_service_enabled(): if EnvService.get_health_service_enabled():
try: try:
process = HealthService().get_process() PROCESS = HealthService().get_process()
except: except:
traceback.print_exc() traceback.print_exc()
print("The health service failed to start.") print("The health service failed to start.")
@ -196,19 +230,14 @@ def init():
asyncio.get_event_loop().run_until_complete(main()) asyncio.get_event_loop().run_until_complete(main())
except KeyboardInterrupt: except KeyboardInterrupt:
print("Caught keyboard interrupt, killing and removing PID") print("Caught keyboard interrupt, killing and removing PID")
os.remove(PID_FILE)
except Exception as e: except Exception as e:
traceback.print_exc() traceback.print_exc()
print(str(e)) print(str(e))
print("Removing PID file") print("Removing PID file")
os.remove(PID_FILE)
finally: finally:
# Kill all threads cleanup_pid_file(None, None)
if process:
print("Killing all subprocesses") sys.exit(0)
process.terminate()
print("Killed all subprocesses")
sys.exit(0)
if __name__ == "__main__": if __name__ == "__main__":

Loading…
Cancel
Save