fix: Add timeout handling to protocol clients to prevent hanging

This commit is contained in:
openhands 2025-11-01 18:46:44 +00:00
parent 400563ac28
commit b15b37658e
1 changed files with 29 additions and 2 deletions

View File

@ -24,9 +24,13 @@ class OPCUAClient:
try:
from asyncua import Client
self._client = Client(url=self.endpoint)
await self._client.connect()
# Set timeout for connection
await asyncio.wait_for(self._client.connect(), timeout=5.0)
logger.info("opcua_client_connected", endpoint=self.endpoint)
return True
except asyncio.TimeoutError:
logger.error("opcua_connection_timeout", endpoint=self.endpoint)
return False
except Exception as e:
logger.error("failed_to_connect_opcua", endpoint=self.endpoint, error=str(e))
return False
@ -45,8 +49,11 @@ class OPCUAClient:
await self.connect()
node = self._client.get_node(node_id)
value = await node.read_value()
value = await asyncio.wait_for(node.read_value(), timeout=3.0)
return value
except asyncio.TimeoutError:
logger.error("opcua_read_timeout", node_id=node_id)
return None
except Exception as e:
logger.error("failed_to_read_opcua_node", node_id=node_id, error=str(e))
return None
@ -115,7 +122,17 @@ class ModbusClient:
if not self._client or not self._client.is_socket_open():
self.connect()
# Set timeout for the read operation
if hasattr(self._client, 'timeout'):
original_timeout = self._client.timeout
self._client.timeout = 2.0 # 2 second timeout
result = self._client.read_holding_registers(address, count)
# Restore original timeout
if hasattr(self._client, 'timeout'):
self._client.timeout = original_timeout
if not result.isError():
return result.registers
else:
@ -131,7 +148,17 @@ class ModbusClient:
if not self._client or not self._client.is_socket_open():
self.connect()
# Set timeout for the read operation
if hasattr(self._client, 'timeout'):
original_timeout = self._client.timeout
self._client.timeout = 2.0 # 2 second timeout
result = self._client.read_input_registers(address, count)
# Restore original timeout
if hasattr(self._client, 'timeout'):
self._client.timeout = original_timeout
if not result.isError():
return result.registers
else: