mirror of
https://github.com/jlu5/PyLink.git
synced 2024-11-27 21:19:31 +01:00
classes: make disconnections more synchronized
- Make ping timer abort instantly if the network is dead - Shut down the read and write parts of the socket separately, and only close the socket once both parts are done.
This commit is contained in:
parent
84dbca4bda
commit
80cbd7a257
27
classes.py
27
classes.py
@ -201,6 +201,7 @@ class PyLinkNetworkCore(structures.CamelCaseToSnakeCase):
|
|||||||
|
|
||||||
self.connected = threading.Event()
|
self.connected = threading.Event()
|
||||||
self._aborted = threading.Event()
|
self._aborted = threading.Event()
|
||||||
|
self._aborted_send = threading.Event()
|
||||||
self._reply_lock = threading.RLock()
|
self._reply_lock = threading.RLock()
|
||||||
|
|
||||||
# Sets the multiplier for autoconnect delay (grows with time).
|
# Sets the multiplier for autoconnect delay (grows with time).
|
||||||
@ -478,6 +479,7 @@ class PyLinkNetworkCore(structures.CamelCaseToSnakeCase):
|
|||||||
"""
|
"""
|
||||||
Implements triggers called before a network connects.
|
Implements triggers called before a network connects.
|
||||||
"""
|
"""
|
||||||
|
self._aborted_send.clear()
|
||||||
self._aborted.clear()
|
self._aborted.clear()
|
||||||
self._init_vars()
|
self._init_vars()
|
||||||
|
|
||||||
@ -1431,6 +1433,7 @@ class IRCNetwork(PyLinkNetworkCoreWithUtils):
|
|||||||
self._selector_key = None
|
self._selector_key = None
|
||||||
self._buffer = b''
|
self._buffer = b''
|
||||||
self._reconnect_thread = None
|
self._reconnect_thread = None
|
||||||
|
self._queue_thread = None
|
||||||
|
|
||||||
def _init_vars(self, *args, **kwargs):
|
def _init_vars(self, *args, **kwargs):
|
||||||
super()._init_vars(*args, **kwargs)
|
super()._init_vars(*args, **kwargs)
|
||||||
@ -1447,6 +1450,9 @@ class IRCNetwork(PyLinkNetworkCoreWithUtils):
|
|||||||
"""Schedules periodic pings in a loop."""
|
"""Schedules periodic pings in a loop."""
|
||||||
self._ping_uplink()
|
self._ping_uplink()
|
||||||
|
|
||||||
|
if self._aborted.is_set():
|
||||||
|
return
|
||||||
|
|
||||||
self._ping_timer = threading.Timer(self.pingfreq, self._schedule_ping)
|
self._ping_timer = threading.Timer(self.pingfreq, self._schedule_ping)
|
||||||
self._ping_timer.daemon = True
|
self._ping_timer.daemon = True
|
||||||
self._ping_timer.name = 'Ping timer loop for %s' % self.name
|
self._ping_timer.name = 'Ping timer loop for %s' % self.name
|
||||||
@ -1521,6 +1527,8 @@ class IRCNetwork(PyLinkNetworkCoreWithUtils):
|
|||||||
try:
|
try:
|
||||||
self._socket.connect((ip, port))
|
self._socket.connect((ip, port))
|
||||||
except (ssl.SSLError, OSError):
|
except (ssl.SSLError, OSError):
|
||||||
|
if world.shutting_down.is_set():
|
||||||
|
return
|
||||||
log.exception('Unable to connect to network %r', self.name)
|
log.exception('Unable to connect to network %r', self.name)
|
||||||
self._start_reconnect()
|
self._start_reconnect()
|
||||||
return
|
return
|
||||||
@ -1637,11 +1645,14 @@ class IRCNetwork(PyLinkNetworkCoreWithUtils):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
log.debug('(%s) disconnect: Shutting down socket.', self.name)
|
log.debug('(%s) disconnect: shutting down read half of socket %s', self.name, self._socket)
|
||||||
self._socket.shutdown(socket.SHUT_RDWR)
|
self._socket.shutdown(socket.SHUT_RD)
|
||||||
except Exception as e: # Socket timed out during creation; ignore
|
except:
|
||||||
log.debug('(%s) error on socket shutdown: %s: %s', self.name, type(e).__name__, e)
|
log.debug('(%s) Error on socket shutdown:', self.name, exc_info=True)
|
||||||
|
|
||||||
|
# Wait for the write half to shut down when applicable.
|
||||||
|
if self._queue_thread is None or self._aborted_send.wait(10):
|
||||||
|
log.debug('(%s) disconnect: closing socket %s', self.name, self._socket)
|
||||||
self._socket.close()
|
self._socket.close()
|
||||||
|
|
||||||
# Stop the queue thread.
|
# Stop the queue thread.
|
||||||
@ -1791,12 +1802,18 @@ class IRCNetwork(PyLinkNetworkCoreWithUtils):
|
|||||||
# The _aborted flag may have changed while we were waiting for an item,
|
# The _aborted flag may have changed while we were waiting for an item,
|
||||||
# so check for it again.
|
# so check for it again.
|
||||||
log.debug('(%s) Stopping queue thread since the connection is dead', self.name)
|
log.debug('(%s) Stopping queue thread since the connection is dead', self.name)
|
||||||
return
|
break
|
||||||
elif data:
|
elif data:
|
||||||
self._send(data)
|
self._send(data)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# Once we're done here, shut down the write part of the socket.
|
||||||
|
if self._socket:
|
||||||
|
log.debug('(%s) _process_queue: shutting down write half of socket %s', self.name, self._socket)
|
||||||
|
self._socket.shutdown(socket.SHUT_WR)
|
||||||
|
self._aborted_send.set()
|
||||||
|
|
||||||
Irc = IRCNetwork
|
Irc = IRCNetwork
|
||||||
|
|
||||||
class Server():
|
class Server():
|
||||||
|
Loading…
Reference in New Issue
Block a user