mirror of
https://github.com/bec-project/bec_widgets.git
synced 2026-05-24 06:58:42 +02:00
feat(rpc-base): set default RPC timeout and allow customization
This commit is contained in:
@@ -222,6 +222,7 @@ class BECGuiClient(RPCBase):
|
||||
self._ipython_registry: dict[str, RPCReference] = {}
|
||||
self.available_widgets = AvailableWidgetsNamespace()
|
||||
register_serializer_extension()
|
||||
self._rpc_timeout = 5
|
||||
|
||||
####################
|
||||
#### Client API ####
|
||||
@@ -232,6 +233,16 @@ class BECGuiClient(RPCBase):
|
||||
"""The launcher object."""
|
||||
return RPCBase(gui_id=f"{self._gui_id}:launcher", parent=self, object_name="launcher")
|
||||
|
||||
def set_rpc_timeout(self, timeout: float):
|
||||
"""Set the timeout for RPC calls to the GUI server.
|
||||
|
||||
Args:
|
||||
timeout(float): The timeout in seconds.
|
||||
"""
|
||||
if not isinstance(timeout, (int, float)) or timeout < 0:
|
||||
raise ValueError("Timeout must be a non-negative number.")
|
||||
self._rpc_timeout = timeout
|
||||
|
||||
def _safe_register_stream(self, endpoint: EndpointInfo, cb: Callable, **kwargs):
|
||||
"""Check if already registered for registration in idempotent functions."""
|
||||
if not self._client.connector.any_stream_is_registered(endpoint, cb=cb):
|
||||
|
||||
@@ -24,6 +24,8 @@ else:
|
||||
|
||||
# pylint: disable=protected-access
|
||||
|
||||
_DEFAULT_RPC_TIMEOUT = object()
|
||||
|
||||
|
||||
def _name_arg(arg):
|
||||
if isinstance(arg, DeviceBaseWithConfig):
|
||||
@@ -154,6 +156,7 @@ class RPCReference:
|
||||
|
||||
|
||||
class RPCBase:
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
gui_id: str | None = None,
|
||||
@@ -211,8 +214,8 @@ class RPCBase:
|
||||
self,
|
||||
method,
|
||||
*args,
|
||||
wait_for_rpc_response=True,
|
||||
timeout=5,
|
||||
wait_for_rpc_response: bool = True,
|
||||
timeout: float | None | object = _DEFAULT_RPC_TIMEOUT,
|
||||
gui_id: str | None = None,
|
||||
**kwargs,
|
||||
) -> Any:
|
||||
@@ -223,13 +226,16 @@ class RPCBase:
|
||||
method: The method to call.
|
||||
args: The arguments to pass to the method.
|
||||
wait_for_rpc_response: Whether to wait for the RPC response.
|
||||
timeout: The timeout for the RPC response.
|
||||
timeout: The timeout for the RPC response. If omitted, the client's default RPC
|
||||
timeout is used. If explicitly set to None, wait indefinitely.
|
||||
gui_id: The GUI ID to use for the RPC call. If None, the default GUI ID is used.
|
||||
kwargs: The keyword arguments to pass to the method.
|
||||
|
||||
Returns:
|
||||
The result of the RPC call.
|
||||
"""
|
||||
if timeout is _DEFAULT_RPC_TIMEOUT:
|
||||
timeout = self._root._rpc_timeout
|
||||
if method in ["show", "hide", "raise"] and gui_id is None:
|
||||
obj = self._root._server_registry.get(self._gui_id)
|
||||
if obj is None:
|
||||
|
||||
@@ -5,6 +5,7 @@ import pytest
|
||||
|
||||
from bec_widgets.cli.client import BECDockArea
|
||||
from bec_widgets.cli.client_utils import BECGuiClient, _start_plot_process
|
||||
from bec_widgets.cli.rpc.rpc_base import RPCBase, RPCResponseTimeoutError, rpc_timeout
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@@ -257,3 +258,11 @@ def test_client_utils_delete_falls_back_to_direct_close():
|
||||
gui.delete("dock")
|
||||
|
||||
widget._run_rpc.assert_called_once_with("close")
|
||||
|
||||
|
||||
def test_client_utils_gui_client_set_rpc_timeout():
|
||||
gui = BECGuiClient()
|
||||
assert gui._rpc_timeout == 5
|
||||
|
||||
gui.set_rpc_timeout(10)
|
||||
assert gui._rpc_timeout == 10
|
||||
|
||||
Reference in New Issue
Block a user