bridge (dbus): Add time out on connection:
- Add a 5s timeout on connection to avoid infinite hang when socket is not working. - Raise `BridgeInitError` on time-out (needed to make `auto` bridge fallback correctly).
This commit is contained in:
parent
25f1aa9178
commit
c6ea6ea27b
4 changed files with 100 additions and 8 deletions
|
|
@ -36,6 +36,7 @@ const_ERROR_PREFIX = const_INT_PREFIX + ".error"
|
|||
const_OBJ_PATH = "/org/libervia/Libervia/bridge"
|
||||
const_CORE_SUFFIX = ".core"
|
||||
const_PLUGIN_SUFFIX = ".plugin"
|
||||
const_CONNECT_TIMEOUT = 5
|
||||
|
||||
|
||||
class ParseError(Exception):
|
||||
|
|
@ -123,7 +124,23 @@ class bridge:
|
|||
|
||||
async def post_init(self):
|
||||
try:
|
||||
self.conn = await client.connect(reactor)
|
||||
d = client.connect(reactor)
|
||||
reactor.callLater(const_CONNECT_TIMEOUT, d.cancel)
|
||||
|
||||
def on_cancel(failure):
|
||||
if failure.check(defer.CancelledError):
|
||||
log.error(
|
||||
f"D-Bus connection timed out after {const_CONNECT_TIMEOUT} s, "
|
||||
"please check the D-Bus service"
|
||||
)
|
||||
return failure
|
||||
|
||||
d.addErrback(on_cancel)
|
||||
self.conn = await d
|
||||
except defer.CancelledError:
|
||||
# The connect deferred was cancelled by the timeout, we raise BridgeInitError
|
||||
# so that the "auto" bridge can fall back to the next one.
|
||||
raise BridgeInitError from None
|
||||
except error.DBusException as e:
|
||||
if e.errName == "org.freedesktop.DBus.Error.NotSupported":
|
||||
log.error(
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
import asyncio
|
||||
from functools import partial
|
||||
|
||||
from twisted.internet import reactor
|
||||
from twisted.internet import defer, reactor
|
||||
from txdbus import client
|
||||
|
||||
from .bridge_frontend import BridgeException
|
||||
|
|
@ -40,6 +40,27 @@ const_OBJ_PATH = "/org/libervia/Libervia/bridge"
|
|||
const_CORE_SUFFIX = ".core"
|
||||
const_PLUGIN_SUFFIX = ".plugin"
|
||||
const_TIMEOUT = 120
|
||||
const_CONNECT_TIMEOUT = 5
|
||||
|
||||
|
||||
def _connect_dbus():
|
||||
"""Connect to the D-Bus session bus with a timeout.
|
||||
|
||||
@return: Deferred to the D-Bus connection
|
||||
"""
|
||||
d = client.connect(reactor)
|
||||
reactor.callLater(const_CONNECT_TIMEOUT, d.cancel)
|
||||
|
||||
def on_cancel(failure):
|
||||
if failure.check(defer.CancelledError):
|
||||
log.error(
|
||||
f"D-Bus connection timed out after {const_CONNECT_TIMEOUT} s, "
|
||||
"please check the D-Bus service"
|
||||
)
|
||||
return failure
|
||||
|
||||
d.addErrback(on_cancel)
|
||||
return d
|
||||
|
||||
|
||||
def dbus_to_bridge_exception(failure):
|
||||
|
|
@ -192,7 +213,7 @@ class bridge:
|
|||
async def bridge_connect(self) -> None:
|
||||
"""Connect to the D-Bus bridge."""
|
||||
try:
|
||||
self.conn = await client.connect(reactor)
|
||||
self.conn = await _connect_dbus()
|
||||
self.db_object = await self.conn.getRemoteObject(
|
||||
const_INT_PREFIX, const_OBJ_PATH
|
||||
)
|
||||
|
|
@ -218,6 +239,10 @@ class bridge:
|
|||
)
|
||||
except BridgeInitError as e:
|
||||
raise e
|
||||
except defer.CancelledError:
|
||||
# The connect deferred was cancelled by the timeout, we raise BridgeInitError
|
||||
# so that the "auto" bridge can fall back to the next one.
|
||||
raise BridgeInitError from None
|
||||
except Exception as e:
|
||||
msg = str(e)
|
||||
if (
|
||||
|
|
@ -281,7 +306,7 @@ class AIOBridge(bridge):
|
|||
async def bridge_connect(self):
|
||||
"""Connect to the D-Bus bridge (async version)."""
|
||||
try:
|
||||
self.conn = await client.connect(reactor).asFuture(asyncio.get_event_loop())
|
||||
self.conn = await _connect_dbus().asFuture(asyncio.get_event_loop())
|
||||
self.db_object = await self.conn.getRemoteObject(
|
||||
const_INT_PREFIX, const_OBJ_PATH
|
||||
).asFuture(asyncio.get_event_loop())
|
||||
|
|
@ -308,6 +333,10 @@ class AIOBridge(bridge):
|
|||
)
|
||||
except BridgeInitError as e:
|
||||
raise e
|
||||
except defer.CancelledError:
|
||||
# The connect deferred was cancelled by the timeout, we raise BridgeInitError
|
||||
# so that the "auto" bridge can fall back to the next one.
|
||||
raise BridgeInitError from None
|
||||
except Exception as e:
|
||||
msg = str(e)
|
||||
if (
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ const_ERROR_PREFIX = const_INT_PREFIX + ".error"
|
|||
const_OBJ_PATH = "/org/libervia/Libervia/bridge"
|
||||
const_CORE_SUFFIX = ".core"
|
||||
const_PLUGIN_SUFFIX = ".plugin"
|
||||
const_CONNECT_TIMEOUT = 5
|
||||
|
||||
|
||||
class ParseError(Exception):
|
||||
|
|
@ -571,7 +572,23 @@ class bridge:
|
|||
|
||||
async def post_init(self):
|
||||
try:
|
||||
self.conn = await client.connect(reactor)
|
||||
d = client.connect(reactor)
|
||||
reactor.callLater(const_CONNECT_TIMEOUT, d.cancel)
|
||||
|
||||
def on_cancel(failure):
|
||||
if failure.check(defer.CancelledError):
|
||||
log.error(
|
||||
f"D-Bus connection timed out after {const_CONNECT_TIMEOUT} s, "
|
||||
"please check the D-Bus service"
|
||||
)
|
||||
return failure
|
||||
|
||||
d.addErrback(on_cancel)
|
||||
self.conn = await d
|
||||
except defer.CancelledError:
|
||||
# The connect deferred was cancelled by the timeout, we raise BridgeInitError
|
||||
# so that the "auto" bridge can fall back to the next one.
|
||||
raise BridgeInitError from None
|
||||
except error.DBusException as e:
|
||||
if e.errName == "org.freedesktop.DBus.Error.NotSupported":
|
||||
log.error(
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
import asyncio
|
||||
from functools import partial
|
||||
|
||||
from twisted.internet import reactor
|
||||
from twisted.internet import defer, reactor
|
||||
from txdbus import client
|
||||
|
||||
from .bridge_frontend import BridgeException
|
||||
|
|
@ -40,6 +40,27 @@ const_OBJ_PATH = "/org/libervia/Libervia/bridge"
|
|||
const_CORE_SUFFIX = ".core"
|
||||
const_PLUGIN_SUFFIX = ".plugin"
|
||||
const_TIMEOUT = 120
|
||||
const_CONNECT_TIMEOUT = 5
|
||||
|
||||
|
||||
def _connect_dbus():
|
||||
"""Connect to the D-Bus session bus with a timeout.
|
||||
|
||||
@return: Deferred to the D-Bus connection
|
||||
"""
|
||||
d = client.connect(reactor)
|
||||
reactor.callLater(const_CONNECT_TIMEOUT, d.cancel)
|
||||
|
||||
def on_cancel(failure):
|
||||
if failure.check(defer.CancelledError):
|
||||
log.error(
|
||||
f"D-Bus connection timed out after {const_CONNECT_TIMEOUT} s, "
|
||||
"please check the D-Bus service"
|
||||
)
|
||||
return failure
|
||||
|
||||
d.addErrback(on_cancel)
|
||||
return d
|
||||
|
||||
|
||||
def dbus_to_bridge_exception(failure):
|
||||
|
|
@ -192,7 +213,7 @@ class bridge:
|
|||
async def bridge_connect(self) -> None:
|
||||
"""Connect to the D-Bus bridge."""
|
||||
try:
|
||||
self.conn = await client.connect(reactor)
|
||||
self.conn = await _connect_dbus()
|
||||
self.db_object = await self.conn.getRemoteObject(
|
||||
const_INT_PREFIX, const_OBJ_PATH
|
||||
)
|
||||
|
|
@ -218,6 +239,10 @@ class bridge:
|
|||
)
|
||||
except BridgeInitError as e:
|
||||
raise e
|
||||
except defer.CancelledError:
|
||||
# The connect deferred was cancelled by the timeout, we raise BridgeInitError
|
||||
# so that the "auto" bridge can fall back to the next one.
|
||||
raise BridgeInitError from None
|
||||
except Exception as e:
|
||||
msg = str(e)
|
||||
if (
|
||||
|
|
@ -963,7 +988,7 @@ class AIOBridge(bridge):
|
|||
async def bridge_connect(self):
|
||||
"""Connect to the D-Bus bridge (async version)."""
|
||||
try:
|
||||
self.conn = await client.connect(reactor).asFuture(asyncio.get_event_loop())
|
||||
self.conn = await _connect_dbus().asFuture(asyncio.get_event_loop())
|
||||
self.db_object = await self.conn.getRemoteObject(
|
||||
const_INT_PREFIX, const_OBJ_PATH
|
||||
).asFuture(asyncio.get_event_loop())
|
||||
|
|
@ -990,6 +1015,10 @@ class AIOBridge(bridge):
|
|||
)
|
||||
except BridgeInitError as e:
|
||||
raise e
|
||||
except defer.CancelledError:
|
||||
# The connect deferred was cancelled by the timeout, we raise BridgeInitError
|
||||
# so that the "auto" bridge can fall back to the next one.
|
||||
raise BridgeInitError from None
|
||||
except Exception as e:
|
||||
msg = str(e)
|
||||
if (
|
||||
|
|
|
|||
Loading…
Reference in a new issue