Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorgan Collett <morgan.collett@gmail.com>2007-07-10 13:55:38 (GMT)
committer Morgan Collett <morgan.collett@gmail.com>2007-07-10 13:55:38 (GMT)
commit3d886d9fc3524711e9cad9d5d47a121edeb363ad (patch)
tree1ce5129c406db076234d4e00416f761c008eb558
parentbe483751a0c291f70636bb702ed838e3adbbb9c0 (diff)
Reapply "Rework reconnection logic so RECONNECT_TIME is interpreted as a minimum, to avoid eating CPU if Avahi or NM becomes unstable (or if dbus-python has the buggy pre-0.82 watch_name_owner() implementation)."
This reverts commit ae18c6f3897ee10a2136b36061dab14d465198b1.
-rw-r--r--src/linklocal_plugin.py14
-rw-r--r--src/server_plugin.py9
-rw-r--r--src/telepathy_plugin.py60
3 files changed, 50 insertions, 33 deletions
diff --git a/src/linklocal_plugin.py b/src/linklocal_plugin.py
index b60eb15..10924e1 100644
--- a/src/linklocal_plugin.py
+++ b/src/linklocal_plugin.py
@@ -68,15 +68,19 @@ class LinkLocalPlugin(TelepathyPlugin):
if unique_name:
self._have_avahi = True
if not had_avahi:
- _logger.info('Avahi appeared on the system bus (%s) - '
- 'starting...', unique_name)
- self.start()
+ if self._backoff_id > 0:
+ _logger.info('Avahi appeared on the system bus (%s) - '
+ 'will start when retry time is reached')
+ else:
+ _logger.info('Avahi appeared on the system bus (%s) - '
+ 'starting...', unique_name)
+ self.start()
else:
self._have_avahi = False
if had_avahi:
_logger.info('Avahi disappeared from the system bus - '
'stopping...')
- self.stop()
+ self._stop()
def cleanup(self):
TelepathyPlugin.cleanup(self)
@@ -85,7 +89,7 @@ class LinkLocalPlugin(TelepathyPlugin):
self._watch = None
def _could_connect(self):
- return self._have_avahi
+ return TelepathyPlugin._could_connect(self) and self._have_avahi
def _get_account_info(self):
"""Retrieve connection manager parameters for this account
diff --git a/src/server_plugin.py b/src/server_plugin.py
index ab00be7..7c275b1 100644
--- a/src/server_plugin.py
+++ b/src/server_plugin.py
@@ -68,12 +68,12 @@ class ServerPlugin(TelepathyPlugin):
if address:
_logger.debug("::: valid IP4 address, conn_status %s",
self._conn_status)
- if self._conn_status == CONNECTION_STATUS_DISCONNECTED:
- _logger.debug("::: will connect")
+ # this is a no-op if starting would be inappropriate right now
+ if self._conn_status != CONNECTION_STATUS_DISCONNECTED:
self.start()
else:
_logger.debug("::: invalid IP4 address, will disconnect")
- self.stop()
+ self._stop()
def _get_account_info(self):
"""Retrieve connection manager parameters for this account
@@ -126,7 +126,8 @@ class ServerPlugin(TelepathyPlugin):
return None
def _could_connect(self):
- return bool(self._ip4am.props.address)
+ return bool(self._ip4am.props.address and
+ TelepathyPlugin._could_connect(self))
def _server_is_trusted(self, hostname):
"""Return True if the server with the given hostname is trusted to
diff --git a/src/telepathy_plugin.py b/src/telepathy_plugin.py
index d28e6a3..a9ddfe0 100644
--- a/src/telepathy_plugin.py
+++ b/src/telepathy_plugin.py
@@ -112,8 +112,8 @@ class TelepathyPlugin(gobject.GObject):
#: The connection's status
self._conn_status = CONNECTION_STATUS_DISCONNECTED
- #: GLib signal ID for reconnections
- self._reconnect_id = 0
+ #: GLib source ID indicating when we may try to reconnect
+ self._backoff_id = 0
#: Parameters for the connection manager
self._account = self._get_account_info()
@@ -156,8 +156,16 @@ class TelepathyPlugin(gobject.GObject):
raise NotImplementedError
def _reconnect_cb(self):
- """Attempt to reconnect to the server"""
+ """Attempt to reconnect to the server after the back-off time has
+ elapsed.
+ """
+ if self._backoff_id > 0:
+ gobject.source_remove(self._backoff_id)
+ self._backoff_id = 0
+
+ # this is a no-op unless _could_connect() returns True
self.start()
+
return False
def _init_connection(self):
@@ -192,9 +200,11 @@ class TelepathyPlugin(gobject.GObject):
_logger.debug('%r: Connect() succeeded', self)
def connect_error(e):
_logger.debug('%r: Connect() failed: %s', self, e)
- if not self._reconnect_id:
- self._reconnect_id = gobject.timeout_add(self._RECONNECT_TIMEOUT,
- self._reconnect_cb)
+ # we don't allow ourselves to retry more often than this
+ if self._backoff_id != 0:
+ gobject.source_remove(self._backoff_id)
+ self._backoff_id = gobject.timeout_add(self._RECONNECT_TIMEOUT,
+ self._reconnect_cb)
self._conn[CONN_INTERFACE].Connect(reply_handler=connect_reply,
error_handler=connect_error)
@@ -228,26 +238,30 @@ class TelepathyPlugin(gobject.GObject):
_logger.debug("%r: connected", self)
self._connected_cb()
elif status == CONNECTION_STATUS_DISCONNECTED:
- self.stop()
+ self._conn = None
+ self._stop()
_logger.debug("%r: disconnected (reason %r)", self, reason)
if reason == CONNECTION_STATUS_REASON_AUTHENTICATION_FAILED:
# FIXME: handle connection failure; retry later?
pass
else:
- # If disconnected, but still have a network connection, retry
- # If disconnected and no network connection, do nothing here
- # and let the IP4AddressMonitor address-changed signal handle
- # reconnection
- if self._could_connect() and not self._reconnect_id:
- self._reconnect_id = gobject.timeout_add(self._RECONNECT_TIMEOUT,
+ # Try again later. We'll detect whether we have a network
+ # connection after the retry period elapses. The fact that
+ # this timer is running also serves as a marker to indicate
+ # that we shouldn't try to go back online yet.
+ if self._backoff_id:
+ gobject.source_remove(self._backoff_id)
+ self._backoff_id = gobject.timeout_add(self._RECONNECT_TIMEOUT,
self._reconnect_cb)
self.emit('status', self._conn_status, int(reason))
def _could_connect(self):
- return True
+ # Don't allow connection unless the reconnect timeout has elapsed,
+ # or this is the first attempt
+ return (self._backoff_id == 0)
- def stop(self):
+ def _stop(self):
"""If we still have a connection, disconnect it"""
matches = self._matches
@@ -266,12 +280,12 @@ class TelepathyPlugin(gobject.GObject):
if self._online_contacts:
self._contacts_offline(self._online_contacts)
- if self._reconnect_id > 0:
- gobject.source_remove(self._reconnect_id)
- self._reconnect_id = 0
-
def cleanup(self):
- self.stop()
+ self._stop()
+
+ if self._backoff_id > 0:
+ gobject.source_remove(self._backoff_id)
+ self._backoff_id = 0
def _contacts_offline(self, handles):
"""Handle contacts going offline (send message, update set)"""
@@ -454,13 +468,11 @@ class TelepathyPlugin(gobject.GObject):
otherwise initiate a connection and transfer control to
_connect_reply_cb or _connect_error_cb
"""
+ if self._conn is not None:
+ return
_logger.debug("%r: Starting up...", self)
- if self._reconnect_id > 0:
- gobject.source_remove(self._reconnect_id)
- self._reconnect_id = 0
-
# Only init connection if we have a valid IP address
if self._could_connect():
self._init_connection()