Ensure the connection is flagged as closed on errors, move #201

This commit is contained in:
Lonami Exo 2017-08-22 23:12:32 +02:00
parent 88ec9c297e
commit 1a6231472e
2 changed files with 26 additions and 20 deletions

View File

@ -4,6 +4,7 @@ import time
from datetime import datetime, timedelta from datetime import datetime, timedelta
from io import BytesIO, BufferedWriter from io import BytesIO, BufferedWriter
from threading import Event, Lock from threading import Event, Lock
import errno
from ..errors import ReadCancelledError from ..errors import ReadCancelledError
@ -43,8 +44,13 @@ class TcpClient:
def close(self): def close(self):
"""Closes the connection""" """Closes the connection"""
if self.connected: if self.connected:
self._socket.shutdown(socket.SHUT_RDWR) try:
self._socket.close() self._socket.shutdown(socket.SHUT_RDWR)
self._socket.close()
except OSError as e:
if e.errno != errno.ENOTCONN:
raise
self.connected = False self.connected = False
self._recreate_socket() self._recreate_socket()
@ -53,18 +59,22 @@ class TcpClient:
# Ensure that only one thread can send data at once # Ensure that only one thread can send data at once
with self._lock: with self._lock:
view = memoryview(data) try:
total_sent, total = 0, len(data) view = memoryview(data)
while total_sent < total: total_sent, total = 0, len(data)
try: while total_sent < total:
sent = self._socket.send(view[total_sent:]) try:
if sent == 0: sent = self._socket.send(view[total_sent:])
raise ConnectionResetError( if sent == 0:
'The server has closed the connection.') raise ConnectionResetError(
total_sent += sent 'The server has closed the connection.')
total_sent += sent
except BlockingIOError: except BlockingIOError:
time.sleep(self.delay) time.sleep(self.delay)
except BrokenPipeError:
self.close()
raise
def read(self, size, timeout=timedelta(seconds=5)): def read(self, size, timeout=timedelta(seconds=5)):
"""Reads (receives) a whole block of 'size bytes """Reads (receives) a whole block of 'size bytes
@ -96,7 +106,7 @@ class TcpClient:
try: try:
partial = self._socket.recv(bytes_left) partial = self._socket.recv(bytes_left)
if len(partial) == 0: if len(partial) == 0:
self.connected = False self.close()
raise ConnectionResetError( raise ConnectionResetError(
'The server has closed the connection.') 'The server has closed the connection.')

View File

@ -321,13 +321,9 @@ class TelegramClient(TelegramBareClient):
try: try:
self(LogOutRequest()) self(LogOutRequest())
# The server may have already disconnected us, we still
# try to disconnect to make sure.
self.disconnect() self.disconnect()
except OSError as e:
# macOS issue: https://github.com/veusz/veusz/issues/54
# Socket has been already closed (Errno 57)
# Fail on any other error
if e.errno != errno.ENOTCONN:
raise
except (RPCError, ConnectionError): except (RPCError, ConnectionError):
# Something happened when logging out, restore the state back # Something happened when logging out, restore the state back
self._sender.logging_out = False self._sender.logging_out = False