[Python] Rosbridge Reconnection not succesfull

Discussão em 'Python' iniciado por Stack, Março 19, 2025.

  1. Stack

    Stack Membro Participativo

    I have a service that is using roslibpy

    class RosConnectorService(AbstractConnectorService):
    def __init__(self):
    self._ros_client = None
    self._ros_connection_task: tasks.Task | None = None
    self._ros_connected_event: asyncio.Event = asyncio.Event()


    async def connect(self):
    logger.debug(f"Attempting to connect to RosBridge")
    retry_count = 5
    self._ros_client = roslibpy.Ros(
    host="localhost",
    port="9090",
    )

    if self._ros_connected_event.is_set():
    self._ros_client.close()

    while True:
    try:
    if not self._ros_client.is_connected:
    self._ros_client.on_ready(self._on_open)
    self._ros_client.connect()
    self._ros_connection_task = asyncio.create_task(run_in_threadpool(self._ros_client.run_forever))

    await asyncio.wait_for(self._ros_connected_event.wait(), timeout=5)
    break
    except asyncio.TimeoutError as e:
    loguru.logger.critical(f"Timeout while connecting: {e}")
    retry_count = self._handle_exception(retry_count)
    if retry_count <= 0:
    if self._ros_connection_task and not self._ros_connection_task.cancelled():
    self._ros_connection_task.cancel()
    return
    logger.debug(f"Retrying to connect... {retry_count} retries left.")
    except ReactorAlreadyRunning:
    logger.debug("Reactor already running. Skipping start.")
    if not self._ros_client.is_connected:
    self._ros_connected_event.set()
    except Exception as e:
    raise Exception(
    f"Disconnected from Rosbridge. Error: {e}")

    def _handle_exception(self, retry_count: int) -> int:
    retry_count -= 1
    loguru.logger.error(
    f"Failed to connect to Rosbridge. "
    f"Retry in 5 seconds")

    if retry_count == 0:
    raise Exception(
    f"Failed to connect to Rosbridge after {retry_count} attempts."
    f"Please check your internet connection")
    return retry_count

    def _on_open(self) -> None:
    logger.debug("Connection to ROSBridge successfully established.")
    self._ros_connected_event.set()

    async def disconnect(self):
    logger.debug("Disconnecting from ROSBridge.")

    if self._ros_connection_task:
    if not self._ros_connection_task.done():
    self._ros_connection_task.cancel()
    try:
    await self._ros_connection_task
    except asyncio.CancelledError:
    logger.debug("ROS connection task successfully cancelled.")

    if self._ros_client:
    self._ros_client.close()
    self._ros_client = None

    self._ros_connected_event.clear()
    self._ros_connected_event = asyncio.Event()


    This service is injected in another service and is called when starting a certain process

    class TestService(AbstractTestService):
    def __init__(self, ros_connector_service: AbstractConnectorService):
    self.ros_connector_service: AbstractConnectorService = ros_connector_service
    self.thread: Thread | None = None
    self.stop_event: Event = Event()
    self.lock: Lock = Lock()
    self.status: str = "idle"

    def start(self):
    if self.thread and self.thread.is_alive():
    logger.warning("Resource busy.")
    return

    with self.lock:
    self.status = "running"
    self.stop_event.clear()
    self.thread = Thread(target=self._run_async_task)
    self.thread.start()

    def _run_async_task(self):
    asyncio.run(self._start_host())

    async def _start_host(self) -> None:
    await self.ros_connector_service.connect()

    try:
    await self.ros_connector_service.toggle_topic(True)

    except Exception as e:
    raise Exception(detail=f"Error during process: {e}")

    finally:
    with self.lock:
    self.status = "idle"
    await self.ros_connector_service.toggle_topic(False)
    await self.ros_connector_service.disconnect()


    When I start the app and run my start function in the ping service, everything is working fine. However, when i terminate the process and restart a new process, im getting this error:

    Task exception was never retrieved
    future: <Task finished name='Task-16' coro=<run_in_threadpool() done, defined at /home/user/projectPython/.venv/lib/python3.10/site-packages/starlette/concurrency.py:35> exception=ReactorAlreadyRunning()>
    Traceback (most recent call last):
    File "/home/user/projectPython/.venv/lib/python3.10/site-packages/starlette/concurrency.py", line 39, in run_in_threadpool
    return await anyio.to_thread.run_sync(func, *args)
    File "/home/user/projectPython/.venv/lib/python3.10/site-packages/anyio/to_thread.py", line 56, in run_sync
    return await get_async_backend().run_sync_in_worker_thread(
    File "/home/user/projectPython/.venv/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 2461, in run_sync_in_worker_thread
    return await future
    File "/home/user/projectPython/.venv/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 962, in run
    result = context.run(func, *args)
    File "/home/user/projectPython/.venv/lib/python3.10/site-packages/roslibpy/ros.py", line 114, in run_forever
    self.factory.manager.run_forever()
    File "/home/user/projectPython/.venv/lib/python3.10/site-packages/roslibpy/comm/comm_autobahn.py", line 190, in run_forever
    reactor.run()
    File "/home/user/projectPython/.venv/lib/python3.10/site-packages/twisted/internet/base.py", line 695, in run
    self.startRunning(installSignalHandlers=installSignalHandlers)
    File "/home/user/projectPython/.venv/lib/python3.10/site-packages/twisted/internet/base.py", line 924, in startRunning
    raise error.ReactorAlreadyRunning()
    twisted.internet.error.ReactorAlreadyRunning


    And then this one if i try to reconnect again

    2025-03-19 12:32:57.081 | ERROR | core.application.services.ros_connector_service:connect:64 - Disconnected from Rosbridge. Error: <asyncio.locks.Event object at 0x70ce46bc4f40 [unset]> is bound to a different event loop
    Traceback (most recent call last):
    File "/home/user/projectPython/src/core/application/services/ros_connector_service.py", line 49, in connect
    await asyncio.wait_for(self._ros_connected_event.wait(), timeout=constants.CONNECTOR_DELAY_CONNECTION)
    File "/usr/lib/python3.10/asyncio/tasks.py", line 445, in wait_for
    return fut.result()
    File "/usr/lib/python3.10/asyncio/locks.py", line 211, in wait
    fut = self._get_loop().create_future()
    File "/usr/lib/python3.10/asyncio/mixins.py", line 30, in _get_loop
    raise RuntimeError(f'{self!r} is bound to a different event loop')
    RuntimeError: <asyncio.locks.Event object at 0x70ce46bc4f40 [unset]> is bound to a different event loop
    During handling of the above exception, another exception occurred:
    Traceback (most recent call last):
    File "/usr/lib/python3.10/threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
    File "/home/user/projectPython/src/core/application/services/ping_service.py", line 64, in _run_async_task
    asyncio.run(self._ping_host(host_ip))
    File "/usr/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
    File "/usr/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
    return future.result()
    File "/home/user/projectPython/src/core/application/services/ping_service.py", line 93, in _ping_host
    await self.ros_connector_service.connect()
    File "/home/user/projectPython/src/core/application/services/ros_connector_service.py", line 68, in connect
    raise DisconnectionFromWebsocketException(
    core.domain.exceptions.base_exceptions: Disconnected from Rosbridge. Error: <asyncio.locks.Event object at 0x70ce46bc4f40 [unset]> is bound to a different event loop
    Exception in thread Thread-7 (_run_async_task):
    Traceback (most recent call last):
    File "/home/user/projectPython/src/core/application/services/ros_connector_service.py", line 49, in connect
    await asyncio.wait_for(self._ros_connected_event.wait(), timeout=constants.CONNECTOR_DELAY_CONNECTION)
    File "/usr/lib/python3.10/asyncio/tasks.py", line 445, in wait_for
    return fut.result()
    File "/usr/lib/python3.10/asyncio/locks.py", line 211, in wait
    fut = self._get_loop().create_future()
    File "/usr/lib/python3.10/asyncio/mixins.py", line 30, in _get_loop
    raise RuntimeError(f'{self!r} is bound to a different event loop')
    RuntimeError: <asyncio.locks.Event object at 0x70ce46bc4f40 [unset]> is bound to a different event loop
    During handling of the above exception, another exception occurred:
    Traceback (most recent call last):
    File "/usr/lib/python3.10/threading.py", line 1016, in _bootstrap_inner
    self.run()
    File "/usr/lib/python3.10/threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
    File "/home/user/projectPython/src/core/application/services/ping_service.py", line 64, in _run_async_task
    asyncio.run(self._ping_host(host_ip))
    File "/usr/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
    File "/usr/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
    return future.result()
    File "/home/user/projectPython/src/core/application/services/ping_service.py", line 93, in _ping_host
    await self.ros_connector_service.connect()
    Disconnected from Rosbridge. Error: <asyncio.locks.Event object at 0x70ce46bc4f40 [unset]> is bound to a different event loop

    Continue reading...

Compartilhe esta Página