From 3ea5a3f7b649fb78a6c8e01b13f6616331dc2bda Mon Sep 17 00:00:00 2001 From: Zevaryx Date: Thu, 24 Jun 2021 23:24:03 -0600 Subject: [PATCH] Proper self-healing --- jarvis/__init__.py | 17 +++++++----- jarvis/cogs/owner.py | 17 ++++++++++++ run.py | 61 +++++++++++++++++++++++++------------------- 3 files changed, 62 insertions(+), 33 deletions(-) diff --git a/jarvis/__init__.py b/jarvis/__init__.py index bdb4498..cb45306 100644 --- a/jarvis/__init__.py +++ b/jarvis/__init__.py @@ -3,11 +3,14 @@ from discord import Intents from discord.ext import commands from discord.utils import find from psutil import Process -from asyncio import sleep +import asyncio from jarvis.config import get_config from jarvis import utils +if asyncio.get_event_loop().is_closed(): + asyncio.set_event_loop(asyncio.new_event_loop()) + intents = Intents.default() intents.members = True @@ -17,9 +20,10 @@ jarvis_self = Process() @jarvis.event async def on_ready(): - print("Logged in as {0.user}".format(jarvis)) - print("Connected to {} guild(s)".format(len(jarvis.guilds))) + print(" Logged in as {0.user}".format(jarvis)) + print(" Connected to {} guild(s)".format(len(jarvis.guilds))) with jarvis_self.oneshot(): + print(f" Current PID: {jarvis_self.pid}") Path(f"jarvis.{jarvis_self.pid}.pid").touch() @@ -33,9 +37,9 @@ async def on_guild_join(guild): + "variety of tasks as best I can, " + "24 hours a day, seven days a week." ) - await sleep(1) + await asyncio.sleep(1) await general.send("Importing all preferences from home interface...") - await sleep(5) + await asyncio.sleep(5) await general.send("Systems are now fully operational") @@ -44,8 +48,7 @@ def run(): jarvis.load_extension(extension) config = get_config() print( - "https://discord.com/api/oauth2/authorize?client_id=" + " https://discord.com/api/oauth2/authorize?client_id=" + "{}&permissions=8&scope=bot".format(config.client_id) ) jarvis.run(config.token, bot=True, reconnect=True) - Path(f"jarvis.{jarvis_self.pid}.pid").unlink() diff --git a/jarvis/cogs/owner.py b/jarvis/cogs/owner.py index 47f4bf9..fe3ec3e 100644 --- a/jarvis/cogs/owner.py +++ b/jarvis/cogs/owner.py @@ -1,5 +1,6 @@ from discord.ext import commands from jarvis.config import get_config +from jarvis.utils import get_prefix class OwnerCog(commands.Cog): @@ -62,6 +63,22 @@ class OwnerCog(commands.Cog): else: await ctx.send("I'm afraid I can't let you do that") + @commands.group(name="system", hidden=True, pass_context=True) + async def _system(self, ctx): + if ctx.invoked_subcommand is None: + await ctx.send( + f"Usage: `{ctx.message.content} `\n" + + "Subcommands: `restart`, `update`" + ) + + @_system.command(name="restart", hidden=True) + async def _restart(self, ctx): + await ctx.send("Restarting core systems...") + try: + await self.bot.close() + except RuntimeError: + pass + def setup(bot): bot.add_cog(OwnerCog(bot)) diff --git a/run.py b/run.py index 0eac9c7..72f9a22 100644 --- a/run.py +++ b/run.py @@ -1,27 +1,22 @@ #!/bin/python3 import jarvis -import os -import signal import git from pathlib import Path -from multiprocessing import Process +from multiprocessing import Value, Process, freeze_support from importlib import reload as ireload from time import sleep def run(): - ireload(jarvis) - jarvis.run() + while True: + ireload(jarvis) + jarvis.run() -jarvis_process = Process(target=run, name="jarvis") - - -def start_process(): +def restart(): global jarvis_process - if jarvis_process.is_alive(): - jarvis_process.terminate() - jarvis_process.join(10) + Path(get_pid_file()).unlink() + jarvis_process.terminate() jarvis_process = Process(target=run, name="jarvis") jarvis_process.start() @@ -42,13 +37,22 @@ def update(): return 1 +def get_pid_file(): + return f"jarvis.{get_pid()}.pid" + + +def get_pid(): + global jarvis_process + return jarvis_process.pid + + def cli(): - pid_file = Path(f"jarvis.{jarvis_process.pid}.pid") - while not pid_file.exists(): + pfile = Path(get_pid_file()) + while not pfile.exists(): sleep(0.2) print( """ - All systems online. + All systems online. Command List: (R)eload @@ -59,15 +63,16 @@ Command List: while True: cmd = input("> ") if cmd.lower() in ["q", "quit", "e", "exit"]: - pid_file.unlink() + print(" Shutting down core systems...") + pfile.unlink() break if cmd.lower() in ["u", "update"]: - print("-> Updating core systems...") + print(" Updating core systems...") status = update() if status == 0: - start_process() - pid_file = Path(f"jarvis.{jarvis_process.pid}.pid") - while not pid_file.exists(): + restart() + pfile = Path(get_pid_file()) + while not pfile.exists(): sleep(0.2) print(" Core systems successfully updated.") elif status == 1: @@ -76,15 +81,17 @@ Command List: print(" Core updates available, but not applied.") if cmd.lower() in ["r", "reload"]: print(" Reloading core systems...") - pid_file.unlink() - start_process() - pid_file = Path(f"jarvis.{jarvis_process.pid}.pid") - while not pid_file.exists(): + restart() + pfile = Path(get_pid_file()) + while not pfile.exists(): sleep(0.2) - print(" All systems reloaded.") + print(" All systems reloaded.") if __name__ == "__main__": + freeze_support() + pid_file = Value("i", 0) + jarvis_process = Process(target=run, name="jarvis") print("J.A.R.V.I.S. initializing....") print(" Updating core systems...") status = update() @@ -94,8 +101,10 @@ if __name__ == "__main__": print(" No core updates available.") elif status == 2: print(" Core updates available, but not applied.") - start_process() + print(" Starting core systems...") + jarvis_process.start() cli() if jarvis_process.is_alive(): jarvis_process.terminate() jarvis_process.join(30) + print("All systems shut down.")