Fenrir was not cleaning up after itself properly. Fixed several possible stale file bugs and hopefully this problem is now gone.

This commit is contained in:
Storm Dragon
2026-05-18 17:59:47 -04:00
parent 096919a2da
commit 19194e73fc
4 changed files with 72 additions and 19 deletions
+5 -2
View File
@@ -106,14 +106,17 @@ def run_fenrir():
fenrirApp.proceed()
except Exception as e:
print(f"Error starting Fenrir: {e}", file=sys.stderr)
sys.exit(1)
except KeyboardInterrupt:
print("Interrupted", file=sys.stderr)
sys.exit(1)
finally:
if fenrirApp and hasattr(fenrirApp, 'cleanup_on_error'):
try:
fenrirApp.cleanup_on_error()
except Exception as cleanup_error:
print(
f"Error during cleanup: {cleanup_error}", file=sys.stderr)
sys.exit(1)
finally:
if fenrirApp:
del fenrirApp
# Clean up PID file if it exists
+27 -15
View File
@@ -5,6 +5,7 @@
# By Chrys, Storm Dragon, and contributors.
import os
import socket
import signal
import sys
import time
@@ -40,6 +41,7 @@ class FenrirManager:
# Set signal handlers after successful initialization
signal.signal(signal.SIGINT, self.capture_signal)
signal.signal(signal.SIGTERM, self.capture_signal)
signal.signal(signal.SIGHUP, self.capture_signal)
self.signal_handlers_set = True
self.is_initialized = True
@@ -381,9 +383,15 @@ class FenrirManager:
time.sleep(0.6)
for currentManager in self.environment["general"]["managerList"]:
if self.environment["runtime"][currentManager]:
self.environment["runtime"][currentManager].shutdown()
del self.environment["runtime"][currentManager]
try:
if (
currentManager in self.environment["runtime"]
and self.environment["runtime"][currentManager]
):
self.environment["runtime"][currentManager].shutdown()
del self.environment["runtime"][currentManager]
except Exception:
pass # Ignore errors during individual manager shutdown
self.environment = None
@@ -394,6 +402,7 @@ class FenrirManager:
if self.signal_handlers_set:
signal.signal(signal.SIGINT, signal.SIG_DFL)
signal.signal(signal.SIGTERM, signal.SIG_DFL)
signal.signal(signal.SIGHUP, signal.SIG_DFL)
self.signal_handlers_set = False
# Clean up any initialized managers
@@ -454,7 +463,6 @@ class FenrirManager:
# Clean up socket files that might not be removed by the driver
try:
socket_file = None
screen_driver = None
if (
"runtime" in self.environment
and "SettingsManager" in self.environment["runtime"]
@@ -465,19 +473,9 @@ class FenrirManager:
].get_setting("remote", "socket_file")
except Exception:
pass # Use default socket file path
try:
screen_driver = self.environment["runtime"][
"SettingsManager"
].get_setting("screen", "driver")
except Exception:
pass
if not socket_file:
if screen_driver == "vcsaDriver":
socket_file = "/tmp/fenrirscreenreader-deamon.sock"
if os.path.exists(socket_file):
os.unlink(socket_file)
# Always clean up PID-specific socket
pid_socket_file = (
"/tmp/fenrirscreenreader-"
+ str(os.getpid())
@@ -485,6 +483,20 @@ class FenrirManager:
)
if os.path.exists(pid_socket_file):
os.unlink(pid_socket_file)
# Clean up main socket only if it is stale (not active)
main_socket_file = "/tmp/fenrirscreenreader-deamon.sock"
if os.path.exists(main_socket_file):
try:
test_sock = socket.socket(
socket.AF_UNIX, socket.SOCK_STREAM
)
test_sock.settimeout(0.2)
test_sock.connect(main_socket_file)
except OSError:
os.unlink(main_socket_file)
finally:
test_sock.close()
elif os.path.exists(socket_file):
os.unlink(socket_file)
remoteInstanceRegistry.remove_instance()
@@ -28,6 +28,7 @@ def write_instance(instance_data):
registry_dir = get_registry_dir()
os.makedirs(registry_dir, mode=0o755, exist_ok=True)
os.chmod(registry_dir, 0o755)
prune_stale_instances()
instance_data["updated_at"] = time.time()
instance_path = get_instance_file(instance_data.get("pid"))
with open(instance_path, "w", encoding="utf-8") as instance_file:
@@ -53,6 +54,39 @@ def process_exists(pid):
return False
def prune_stale_instances():
registry_dir = get_registry_dir()
try:
instance_files = os.listdir(registry_dir)
except FileNotFoundError:
return
now = time.time()
for instance_name in instance_files:
instance_path = os.path.join(registry_dir, instance_name)
try:
with open(instance_path, "r", encoding="utf-8") as instance_file:
instance_data = json.load(instance_file)
pid = int(instance_data.get("pid", 0))
updated_at = float(instance_data.get("updated_at", 0))
except (OSError, ValueError, TypeError, json.JSONDecodeError):
try:
os.unlink(instance_path)
except OSError:
pass
continue
if (
not pid
or not process_exists(pid)
or now - updated_at > INSTANCE_TIMEOUT_SEC
):
try:
os.unlink(instance_path)
except OSError:
pass
def list_instances():
registry_dir = get_registry_dir()
instances = []
@@ -72,7 +106,11 @@ def list_instances():
except (OSError, ValueError, TypeError, json.JSONDecodeError):
continue
if not pid or not process_exists(pid) or now - updated_at > INSTANCE_TIMEOUT_SEC:
if (
not pid
or not process_exists(pid)
or now - updated_at > INSTANCE_TIMEOUT_SEC
):
try:
os.unlink(instance_path)
except OSError:
+1 -1
View File
@@ -4,5 +4,5 @@
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributors.
version = "2026.05.14"
version = "2026.05.18"
code_name = "testing"