summaryrefslogtreecommitdiff
path: root/backend/decky_loader/main.py
diff options
context:
space:
mode:
authorAAGaming <aagaming@riseup.net>2024-08-07 16:14:18 -0400
committerAAGaming <aagaming@riseup.net>2024-08-07 16:14:18 -0400
commit65b6883dcc42944607eb0efa1f28e41f57335313 (patch)
tree38db3185d6720552daa978149279928d271df19a /backend/decky_loader/main.py
parent166c7ea8a7ea74d9a61d84ebe16556cec9e7cc83 (diff)
downloaddecky-loader-65b6883dcc42944607eb0efa1f28e41f57335313.tar.gz
decky-loader-65b6883dcc42944607eb0efa1f28e41f57335313.zip
handle crashloops and disable decky for the user
Diffstat (limited to 'backend/decky_loader/main.py')
-rw-r--r--backend/decky_loader/main.py29
1 files changed, 27 insertions, 2 deletions
diff --git a/backend/decky_loader/main.py b/backend/decky_loader/main.py
index 5033126e..c268b387 100644
--- a/backend/decky_loader/main.py
+++ b/backend/decky_loader/main.py
@@ -15,6 +15,7 @@ from asyncio import AbstractEventLoop, CancelledError, Task, all_tasks, current_
from logging import basicConfig, getLogger
from os import path
from traceback import format_exc
+from time import time
import aiohttp_cors # pyright: ignore [reportMissingTypeStubs]
# Partial imports
@@ -25,7 +26,7 @@ from setproctitle import getproctitle, setproctitle, setthreadtitle
# local modules
from .browser import PluginBrowser
-from .helpers import (REMOTE_DEBUGGER_UNIT, csrf_middleware, get_csrf_token, get_loader_version,
+from .helpers import (REMOTE_DEBUGGER_UNIT, create_inject_script, csrf_middleware, get_csrf_token, get_loader_version,
mkdir_as_user, get_system_pythonpaths, get_effective_user_id)
from .injector import get_gamepadui_tab, Tab
@@ -75,6 +76,9 @@ class PluginManager:
self.plugin_browser = PluginBrowser(plugin_path, self.plugin_loader.plugins, self.plugin_loader, self.settings)
self.utilities = Utilities(self)
self.updater = Updater(self)
+ self.last_webhelper_exit: float = 0
+ self.webhelper_crash_count: int = 0
+ self.inject_fallback: bool = False
jinja_setup(self.web_app)
@@ -96,6 +100,21 @@ class PluginManager:
self.cors.add(route) # pyright: ignore [reportUnknownMemberType]
self.web_app.add_routes([static("/static", path.join(path.dirname(__file__), 'static'))])
+ async def handle_crash(self):
+ new_time = time()
+ if (new_time - self.last_webhelper_exit < 60):
+ self.webhelper_crash_count += 1
+ logger.warn(f"webhelper crashed within a minute from last crash! crash count: {self.webhelper_crash_count}")
+ else:
+ self.webhelper_crash_count = 0
+ self.last_webhelper_exit = new_time
+
+ # should never happen
+ if (self.webhelper_crash_count > 4):
+ await self.updater.do_shutdown()
+ # Give up
+ exit(0)
+
async def shutdown(self, _: Application):
try:
logger.info(f"Shutting down...")
@@ -187,6 +206,7 @@ class PluginManager:
# If this is a forceful disconnect the loop will just stop without any failure message. In this case, injector.py will handle this for us so we don't need to close the socket.
# This is because of https://github.com/aio-libs/aiohttp/blob/3ee7091b40a1bc58a8d7846e7878a77640e96996/aiohttp/client_ws.py#L321
logger.info("CEF has disconnected...")
+ await self.handle_crash()
# At this point the loop starts again and we connect to the freshly started Steam client once it is ready.
except Exception:
if not self.reinject:
@@ -194,6 +214,7 @@ class PluginManager:
logger.error("Exception while reading page events " + format_exc())
await tab.close_websocket()
self.js_ctx_tab = None
+ await self.handle_crash()
pass
# while True:
# await sleep(5)
@@ -211,7 +232,11 @@ class PluginManager:
await restart_webhelper()
await sleep(1) # To give CEF enough time to close down the websocket
return # We'll catch the next tab in the main loop
- await tab.evaluate_js("try{if (window.deckyHasLoaded){setTimeout(() => SteamClient.Browser.RestartJSContext(), 100)}else{window.deckyHasLoaded = true;(async()=>{try{await import('http://localhost:1337/frontend/index.js?v=%s')}catch(e){console.error(e)};})();}}catch(e){console.error(e)}" % (get_loader_version(), ), False, False, False)
+ await tab.evaluate_js(create_inject_script("index.js" if self.webhelper_crash_count < 3 else "fallback.js"), False, False, False)
+ if self.webhelper_crash_count > 2:
+ self.reinject = False
+ await sleep(1)
+ await self.updater.do_shutdown()
except:
logger.info("Failed to inject JavaScript into tab\n" + format_exc())
pass