I have a long-running task that processes an input file and then uploads it to a web server. The processing part can be interrupted (with cleanup) but the upload shouldn't be interruptable so that we know whether the server received the file correctly.
My thread looks like this (I'm using PyQt but I imagine this problem occurs in other threading modules too):
class ImportThread(QtCore.QThread):
def __init__(self, path):
super(ImportThread, self).__init__()
self.path = path
self.stopped = False
@property
def stopped(self):
return self._stopped
@stopped.setter
def stopped(self, stopped):
self._stopped = stopped
def run(self):
self.emit(QtCore.SIGNAL("processing()"))
# Do the processing task unless the thread has already been stopped
if not self.stopped:
do_processing_task()
# Don't move on to the next step if the thread has been stopped
if not self.stopped:
self.emit(QtCore.SIGNAL("uploading()"))
else:
cleanup_processed_file()
return # Exit thread
do_upload_task()
self.emit(QtCore.SIGNAL("completed()"))
I don't think the nested if
s are very readable and am looking for a way to clean this up. Any suggestions?
Usage looks a little like this:
# triggering thread
self.thread = ImportThread(path)
# ... connects() to thread signals that update the progress dialog ...
self.thread.start()
# Create a progress dialog to monitor the thread
self.progress = QtGui.QProgressDialog("Starting...", "Cancel", 0, 2, self)
self.progress.setValue(0)
self.progress.show()
# Connect cancellation signal from progress dialog to method to stop the thread
self.connect(self.progress, QtCore.SIGNAL("canceled()"), self.notify_cancelled)
def notify_cancelled(self):
self.progress.setLabelText("Cancelling...")
self.thread.stopped = True
self.thread.exit() # Not sure this is correct?
self.progress.close()