fix: monitor worker non-blocking + test fixes

- core/monitor.py: add fast metrics script (0.3s vs 1.4s sleep),
  collect() now defaults to fast=True for responsive UI
- ui/workers.py: MonitorWorker changed from loop mode to single-shot
  (QTimer re-arms next cycle on finished signal, avoids paramiko
  blocking in infinite loop)
- ui/widgets.py: remove debug print from _kick_one_sample
- test_monitor_nonblock.py: fix sample counting by wrapping _on_sample
  instead of disconnecting signals (old approach missed new workers)
- test_process_monitor.py: assertions account for MAX_RENDER_ROWS=200,
  fix MEM% column index (4 not 3) in sort test
This commit is contained in:
Your Name
2026-07-28 22:57:15 +08:00
parent 5e69b1c3e2
commit 5d83348db3
5 changed files with 341 additions and 33 deletions
+14 -12
View File
@@ -50,8 +50,8 @@ class CommandWorker(QThread):
self.finished_with.emit(code, out, err)
class MonitorWorker(QThread):
"""后台采集系统指标;循环模式"""
class _SystemMonitorWorker(QThread):
"""单次采集 + QTimer 周期触发(避免 run() 死循环 + paramiko 阻塞问题)"""
sample_ready = pyqtSignal(dict)
error = pyqtSignal(str)
@@ -65,16 +65,18 @@ class MonitorWorker(QThread):
self._stop = True
def run(self):
while not self._stop:
try:
m = SystemMonitor.collect(self.conn)
self.sample_ready.emit(m)
except Exception as e:
self.error.emit(str(e))
for _ in range(self.interval * 10):
if self._stop:
return
time.sleep(0.1)
"""单次采集一帧;由主线程用 QTimer 调度下一次"""
if self._stop:
return
try:
m = SystemMonitor.collect(self.conn)
self.sample_ready.emit(m)
except Exception as e:
self.error.emit(str(e))
# 保留旧类名做兼容(一些其他地方可能引用了 MonitorWorker
MonitorWorker = _SystemMonitorWorker
class UploadWorker(QThread):