refactor: 复用持久设备工作线程 (#110)

This commit is contained in:
chengma
2026-08-10 18:00:38 +08:00
parent 553659208a
commit 70cedc34d4
11 changed files with 563 additions and 149 deletions
+88 -1
View File
@@ -3,7 +3,13 @@
import threading
import unittest
from src.pdd_device_service import PddDeviceError, PddDeviceService
from src.pdd_device_service import (
PddDeviceError,
PddDeviceService,
PersistentPddDeviceService,
bind_thread_device_service,
current_thread_device_service,
)
from src.performance_timing import TaskPerformanceTrace
@@ -89,5 +95,86 @@ class PddDeviceServiceTest(unittest.TestCase):
self.assertEqual(errors, ["DEVICE_THREAD_VIOLATION"])
class PersistentPddDeviceServiceTest(unittest.TestCase):
def test_same_serial_within_ttl_connects_once_but_checks_each_task(self):
connected = []
device = FakeDevice()
service = PersistentPddDeviceService(
lambda serial: connected.append(serial) or device,
ttl_seconds=90,
)
with service.connect("USB-001"):
pass
with service.connect("USB-001"):
pass
self.assertEqual(connected, ["USB-001"])
self.assertEqual(device.current_calls, 2)
def test_expired_or_changed_serial_discards_cached_connection(self):
now = [10.0]
connected = []
service = PersistentPddDeviceService(
lambda serial: connected.append(serial) or FakeDevice(),
ttl_seconds=5,
monotonic=lambda: now[0],
)
with service.connect("USB-001"):
pass
now[0] = 16.0
with service.connect("USB-001"):
pass
with service.connect("USB-002"):
pass
self.assertEqual(connected, ["USB-001", "USB-001", "USB-002"])
def test_failed_cached_health_check_reconnects_only_once(self):
class UnhealthyDevice(FakeDevice):
def app_current(self):
self.current_calls += 1
if self.current_calls >= 2:
raise OSError("offline")
return {"package": "com.xunmeng.pinduoduo"}
devices = [UnhealthyDevice(), FakeDevice()]
connected = []
service = PersistentPddDeviceService(
lambda serial: connected.append(serial) or devices.pop(0)
)
with service.connect("USB-001"):
pass
with service.connect("USB-001") as current:
self.assertIsInstance(current, FakeDevice)
self.assertEqual(connected, ["USB-001", "USB-001"])
def test_release_and_context_binding_stay_on_owner_thread(self):
service = PersistentPddDeviceService(lambda _serial: FakeDevice())
with service.connect("USB-001"):
pass
with bind_thread_device_service(service):
self.assertIs(current_thread_device_service(), service)
self.assertIsNone(current_thread_device_service())
errors = []
def release_from_other_thread():
try:
service.release_cached()
except PddDeviceError as exc:
errors.append(exc.code)
worker = threading.Thread(target=release_from_other_thread)
worker.start()
worker.join()
self.assertEqual(errors, ["DEVICE_THREAD_VIOLATION"])
service.release_cached()
self.assertFalse(service.has_cached_device)
if __name__ == "__main__":
unittest.main()