Avoid using 'terminate' on the download thread

This commit is contained in:
alessandro90
2019-06-09 12:39:26 +02:00
parent 34d197c2ed
commit 52c41b24ad
2 changed files with 42 additions and 33 deletions

View File

@@ -5,6 +5,7 @@ from threads import DownloadThread, ThreadStatus
from utilities import pop_up, resource_path from utilities import pop_up, resource_path
from constants import Constants, Messages from constants import Constants, Messages
Ui_Download_window, _ = uic.loadUiType( Ui_Download_window, _ = uic.loadUiType(
resource_path("download_db_window.ui") resource_path("download_db_window.ui")
) )
@@ -14,6 +15,7 @@ class DownloadWindow(QWidget, Ui_Download_window):
"""Subclass QWidget and Ui_Download_window. It is the window displayed during the database download.""" """Subclass QWidget and Ui_Download_window. It is the window displayed during the database download."""
complete = pyqtSignal() complete = pyqtSignal()
closed = pyqtSignal()
def __init__(self): def __init__(self):
"""Initialize the window.""" """Initialize the window."""
@@ -38,6 +40,7 @@ class DownloadWindow(QWidget, Ui_Download_window):
self._download_thread = DownloadThread() self._download_thread = DownloadThread()
self._download_thread.finished.connect(self._wait_close) self._download_thread.finished.connect(self._wait_close)
self._download_thread.progress.connect(self._display_progress) self._download_thread.progress.connect(self._display_progress)
self.closed.connect(self._download_thread.set_exit)
self.cancel_btn.clicked.connect(self._terminate_process) self.cancel_btn.clicked.connect(self._terminate_process)
def start_download(self): def start_download(self):
@@ -61,12 +64,16 @@ class DownloadWindow(QWidget, Ui_Download_window):
elif progress == Constants.EXTRACTING_CODE: elif progress == Constants.EXTRACTING_CODE:
self.status_lbl.setText(Constants.EXTRACTING_MSG + '\n') self.status_lbl.setText(Constants.EXTRACTING_MSG + '\n')
def _stop_thread(self):
"""Ask the download thread to stop."""
if self._download_thread.isRunning():
self.closed.emit()
self._download_thread.wait()
@pyqtSlot() @pyqtSlot()
def _terminate_process(self): def _terminate_process(self):
"""Terminate the download thread and close.""" """Terminate the download thread and close."""
if self._download_thread.isRunning(): self._stop_thread()
self._download_thread.terminate()
self._download_thread.wait()
self.close() self.close()
@pyqtSlot() @pyqtSlot()
@@ -84,7 +91,5 @@ class DownloadWindow(QWidget, Ui_Download_window):
def reject(self): def reject(self):
"""Extends QWidget.reject. Terminate the download thread.""" """Extends QWidget.reject. Terminate the download thread."""
if self._download_thread.isRunning(): self._stop_thread()
self._download_thread.terminate()
self._download_thread.wait()
super().reject() super().reject()

View File

@@ -41,16 +41,17 @@ class DownloadThread(BaseDownloadThread):
"""Subclass BaseDownloadThread. Download the database, images and audio samples.""" """Subclass BaseDownloadThread. Download the database, images and audio samples."""
progress = pyqtSignal(int, float) progress = pyqtSignal(int, float)
CHUNK = 1024**2 _CHUNK = 1024**2
def __init__(self): def __init__(self):
"""Just call super().__init__.""" """Just call super().__init__."""
self.db = None self._db = None
self._exit_call = False
super().__init__() super().__init__()
def _pretty_len(self, byte_obj): def _pretty_len(self, byte_obj):
"""Return a well-formatted number of downloaded MB.""" """Return a well-formatted number of downloaded MB."""
mega = len(byte_obj) / self.CHUNK mega = len(byte_obj) / self._CHUNK
if mega.is_integer(): if mega.is_integer():
return int(mega) return int(mega)
else: else:
@@ -59,40 +60,51 @@ class DownloadThread(BaseDownloadThread):
def _get_download_speed(self, data, delta): def _get_download_speed(self, data, delta):
"""Return the download speed in MB/s.""" """Return the download speed in MB/s."""
return round( return round(
(len(data) / self.CHUNK) / delta, 2 (len(data) / self._CHUNK) / delta, 2
) )
def set_exit(self):
self._exit_call = True
def run(self): def run(self):
"""Override QThread.run. Download the database, images and audio samples. """Override QThread.run. Download the database, images and audio samples.
Handle all possible exceptions. Also extract the files Handle all possible exceptions. Also extract the files
in the local folder.""" in the local folder."""
self.status = ThreadStatus.UNDEFINED self.status = ThreadStatus.UNDEFINED
self.db = None self._db = None
raw_data = bytes(0) raw_data = bytes(0)
try: try:
self.db = urllib3.PoolManager().request( self._db = urllib3.PoolManager().request(
'GET', 'GET',
Database.LINK_LOC, Database.LINK_LOC,
preload_content=False preload_content=False,
timeout=4.0
) )
while True: while True:
start = time() start = time()
data = self.db.read(self.CHUNK) try:
delta = time() - start data = self._db.read(self._CHUNK)
if not data: except Exception:
break raise
raw_data += data else:
self.progress.emit( delta = time() - start
self._pretty_len(raw_data), if not data:
self._get_download_speed(data, delta) break
) raw_data += data
self.db.release_conn() self.progress.emit(
self._pretty_len(raw_data),
self._get_download_speed(data, delta)
)
if self._exit_call:
self._exit_call = False
self._db.release_conn()
return
except Exception: # No internet connection. except Exception: # No internet connection.
self.db.release_conn() self._db.release_conn()
self.status = ThreadStatus.NO_CONNECTION_ERR self.status = ThreadStatus.NO_CONNECTION_ERR
return return
if self.db.status != 200: if self._db.status != 200:
self.status = ThreadStatus.BAD_DOWNLOAD_ERR self.status = ThreadStatus.BAD_DOWNLOAD_ERR
return return
try: try:
@@ -115,14 +127,6 @@ class DownloadThread(BaseDownloadThread):
else: else:
self.status = ThreadStatus.OK self.status = ThreadStatus.OK
def terminate(self):
"""Extend QThread.terminate.
Release the connection in case of termination."""
if self.db is not None:
self.db.release_conn()
super().terminate()
class _AsyncDownloader: class _AsyncDownloader:
"""Mixin class for asynchronous threads.""" """Mixin class for asynchronous threads."""