Sfoglia il codice sorgente

Fix race condition with stale serial port from wrong backend

When using multi-table mode, the frontend could receive serial port data
from a different backend during the brief window before TableContext
validates the active table URL. This caused connect attempts with
non-existent ports (e.g., Mac's /dev/cu.usbserial on a Pi).

Fix: Validate that the port returned from /serial_status exists in the
available ports list from /list_serial_ports before setting it. If the
port doesn't exist on this machine, log a warning and ignore it.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
tuanchris 2 settimane fa
parent
commit
d970b0f611

+ 12 - 3
frontend/src/pages/SettingsPage.tsx

@@ -293,16 +293,25 @@ export function SettingsPage() {
 
   const fetchPorts = async () => {
     try {
-      // Fetch available ports
+      // Fetch available ports first
       const portsData = await apiClient.get<string[]>('/list_serial_ports')
-      setPorts(portsData || [])
+      const availablePorts = portsData || []
+      setPorts(availablePorts)
 
       // Fetch connection status
       const statusData = await apiClient.get<{ connected: boolean; port?: string }>('/serial_status')
       setIsConnected(statusData.connected || false)
       setConnectionStatus(statusData.connected ? 'Connected' : 'Disconnected')
-      if (statusData.port) {
+
+      // Only set selectedPort if it exists in the available ports list
+      // This prevents race conditions where stale port data from a different
+      // backend (e.g., Mac port on a Pi) could be set
+      if (statusData.port && availablePorts.includes(statusData.port)) {
         setSelectedPort(statusData.port)
+      } else if (statusData.port && !availablePorts.includes(statusData.port)) {
+        // Port from status doesn't exist on this machine - likely stale data
+        console.warn(`Port ${statusData.port} from status not in available ports, ignoring`)
+        setSelectedPort('')
       }
     } catch (error) {
       console.error('Error fetching ports:', error)

+ 13 - 3
frontend/src/pages/TableControlPage.tsx

@@ -259,11 +259,21 @@ export function TableControlPage() {
 
   const fetchMainConnectionStatus = async () => {
     try {
+      // Fetch available ports first to validate against
+      const portsData = await apiClient.get<string[]>('/list_serial_ports')
+      const availablePorts = Array.isArray(portsData) ? portsData : []
+
       const data = await apiClient.get<{ connected: boolean; port?: string }>('/serial_status')
       if (data.connected && data.port) {
-        setMainConnectionPort(data.port)
-        // Auto-select the connected port
-        setSelectedSerialPort(data.port)
+        // Only set port if it exists in available ports
+        // This prevents race conditions where stale port data from a different
+        // backend (e.g., Mac port on a Pi) could be set and auto-connected
+        if (availablePorts.includes(data.port)) {
+          setMainConnectionPort(data.port)
+          setSelectedSerialPort(data.port)
+        } else {
+          console.warn(`Port ${data.port} from status not in available ports, ignoring`)
+        }
       }
     } catch {
       // Ignore errors