fix(updater): keep auto-updater alive across watcher restarts (v0.4.1)
Saving the Settings dialog calls _restart_watcher, which set+replaced the shared stop_event the updater loop also keyed off — so a settings save silently killed the auto-updater thread (race: survived one save, died on the next). Heartbeats kept flowing but the agent stopped checking for / applying updates until relaunch. Give the updater its own app-lifetime event (_app_stop), set only on Exit / when applying an update and untouched by watcher restarts. Adds test_thor_tray.py (4 lifecycle tests). Bump to v0.4.1. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+7
-4
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
Thor Watcher — System Tray Launcher v0.4.0
|
||||
Thor Watcher — System Tray Launcher v0.4.1
|
||||
Requires: pystray, Pillow, tkinter (stdlib)
|
||||
|
||||
Run with: pythonw thor_tray.py (no console window)
|
||||
@@ -334,7 +334,8 @@ def _show_cancel_message():
|
||||
class WatcherTray:
|
||||
def __init__(self):
|
||||
self.state = {}
|
||||
self.stop_event = threading.Event()
|
||||
self.stop_event = threading.Event() # watcher lifecycle; replaced on restart
|
||||
self._app_stop = threading.Event() # app lifetime; only set on exit/update
|
||||
self._watcher_thread = None
|
||||
self._icon = None
|
||||
self._menu_lock = threading.Lock()
|
||||
@@ -390,6 +391,7 @@ class WatcherTray:
|
||||
subprocess.Popen(["explorer", HERE])
|
||||
|
||||
def _exit(self, icon, item):
|
||||
self._app_stop.set()
|
||||
self.stop_event.set()
|
||||
icon.stop()
|
||||
|
||||
@@ -478,7 +480,7 @@ class WatcherTray:
|
||||
# line in the log soon after startup; subsequent checks every ~5 min.
|
||||
update_check_counter = 27
|
||||
|
||||
while not self.stop_event.is_set():
|
||||
while not self._app_stop.is_set():
|
||||
icon_status = self._tray_status()
|
||||
|
||||
if self._icon is not None:
|
||||
@@ -504,7 +506,7 @@ class WatcherTray:
|
||||
self._do_update(url)
|
||||
return
|
||||
|
||||
self.stop_event.wait(timeout=10)
|
||||
self._app_stop.wait(timeout=10)
|
||||
|
||||
def _do_update(self, download_url=None):
|
||||
"""Notify tray then apply update. If url is None, fetch it first."""
|
||||
@@ -519,6 +521,7 @@ class WatcherTray:
|
||||
|
||||
success = apply_update(download_url)
|
||||
if success:
|
||||
self._app_stop.set()
|
||||
self.stop_event.set()
|
||||
if self._icon is not None:
|
||||
self._icon.stop()
|
||||
|
||||
Reference in New Issue
Block a user