diff options
| author | AAGaming <aagaming@riseup.net> | 2024-09-11 20:35:24 -0400 |
|---|---|---|
| committer | AAGaming <aagaming@riseup.net> | 2024-09-11 20:35:24 -0400 |
| commit | 508408ad5ae3da687080210d4ad68608eda65d85 (patch) | |
| tree | 406bc0f2e83b4dcec0533f2e8a8a5cedc0288c86 /backend/decky_loader | |
| parent | ef4ca204bdce6b06072b9fb28d709742052a0c2c (diff) | |
| download | decky-loader-508408ad5ae3da687080210d4ad68608eda65d85.tar.gz decky-loader-508408ad5ae3da687080210d4ad68608eda65d85.zip | |
use signals to shut down plugins instead of sending a socket messagev3.0.0-pre13
should reduce or outright prevent shutdown stalls
Diffstat (limited to 'backend/decky_loader')
| -rw-r--r-- | backend/decky_loader/plugin/plugin.py | 27 | ||||
| -rw-r--r-- | backend/decky_loader/plugin/sandboxed_plugin.py | 9 |
2 files changed, 20 insertions, 16 deletions
diff --git a/backend/decky_loader/plugin/plugin.py b/backend/decky_loader/plugin/plugin.py index 28be710d..ba23fff9 100644 --- a/backend/decky_loader/plugin/plugin.py +++ b/backend/decky_loader/plugin/plugin.py @@ -120,18 +120,25 @@ class PluginWrapper: start_time = time() if self.passive: return + self.log.info(f"Shutting down {self.name}") - _, pending = await wait([ - create_task(self._socket.write_single_line(dumps({ "stop": True, "uninstall": uninstall }, ensure_ascii=False))) - ], timeout=1) + pending: set[Task[None]] | None = None; + + if uninstall: + _, pending = await wait([ + create_task(self._socket.write_single_line(dumps({ "uninstall": uninstall }, ensure_ascii=False))) + ], timeout=1) + + self.terminate() # the plugin process will handle SIGTERM and shut down cleanly without a socket message if hasattr(self, "_listener_task"): self._listener_task.cancel() await self.kill_if_still_running() - for pending_task in pending: - pending_task.cancel() + if pending: + for pending_task in pending: + pending_task.cancel() self.log.info(f"Plugin {self.name} has been stopped in {time() - start_time:.1f}s") except Exception as e: @@ -139,18 +146,14 @@ class PluginWrapper: async def kill_if_still_running(self): start_time = time() - sigtermed = False while self.proc and self.proc.is_alive(): elapsed_time = time() - start_time - if elapsed_time >= 5 and not sigtermed: - sigtermed = True - self.log.warning(f"Plugin {self.name} still alive 5 seconds after stop request! Sending SIGTERM!") - self.terminate() - elif elapsed_time >= 10: - self.log.warning(f"Plugin {self.name} still alive 10 seconds after stop request! Sending SIGKILL!") + if elapsed_time >= 5: + self.log.warning(f"Plugin {self.name} still alive 5 seconds after stop request! Sending SIGKILL!") self.terminate(True) await sleep(0.1) + def terminate(self, kill: bool = False): if self.proc and self.proc.is_alive(): if kill: diff --git a/backend/decky_loader/plugin/sandboxed_plugin.py b/backend/decky_loader/plugin/sandboxed_plugin.py index b730fa98..6223fd04 100644 --- a/backend/decky_loader/plugin/sandboxed_plugin.py +++ b/backend/decky_loader/plugin/sandboxed_plugin.py @@ -40,6 +40,7 @@ class SandboxedPlugin: self.author = author self.api_version = api_version self.shutdown_running = False + self.uninstalling = False self.log = getLogger("sandboxed_plugin") @@ -161,13 +162,13 @@ class SandboxedPlugin: self.log.error("Failed to uninstall " + self.name + "!\n" + format_exc()) pass - async def shutdown(self, uninstall: bool = False): + async def shutdown(self): if not self.shutdown_running: self.shutdown_running = True self.log.info(f"Calling Loader unload function for {self.name}.") await self._unload() - if uninstall: + if self.uninstalling: self.log.info("Calling Loader uninstall function.") await self._uninstall() @@ -180,8 +181,8 @@ class SandboxedPlugin: async def on_new_message(self, message : str) -> str|None: data = loads(message) - if "stop" in data: - await self.shutdown(data.get('uninstall')) + if "uninstall" in data: + self.uninstalling = data.get("uninstall") d: SocketResponseDict = {"type": SocketMessageType.RESPONSE, "res": None, "success": True, "id": data["id"]} try: |
