Skip to content

Commit

Permalink
OWLouvain: Fix crash when changing paramters too quickly
Browse files Browse the repository at this point in the history
  • Loading branch information
pavlin-policar committed Jul 17, 2018
1 parent 6c5231c commit e5e3796
Showing 1 changed file with 18 additions and 11 deletions.
29 changes: 18 additions & 11 deletions Orange/widgets/unsupervised/owlouvainclustering.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,16 @@ class TaskQueue(QObject):
on_exception = Signal(Exception)
on_complete = Signal()
on_progress = Signal(float)
on_cancel = Signal()

def __init__(self, parent=None):
super().__init__(parent=parent)
self.__tasks = deque()
self.__progress = 0
self.__cancelled = False

def cancel(self):
self.__cancelled = True

def push(self, task):
self.__tasks.append(task)
Expand All @@ -62,6 +67,10 @@ def start(self):

for idx, task_spec in enumerate(self.__tasks):

if self.__cancelled:
self.on_cancel.emit()
return

def __task_progress(percentage):
current_progress = idx / num_tasks
# How much progress can each task contribute to the total
Expand All @@ -81,7 +90,7 @@ def __task_progress(percentage):

except Exception as e:
self.on_exception.emit(e)
break
return

self.on_complete.emit()

Expand Down Expand Up @@ -118,9 +127,6 @@ class Error(widget.OWWidget.Error):
empty_dataset = Msg('No features in data')
general_error = Msg('Error occured during clustering\n{}')

class State(Enum):
Pending, Running = range(2)

def __init__(self):
super().__init__()

Expand All @@ -131,7 +137,7 @@ def __init__(self):

self.__executor = ThreadExecutor(parent=self)
self.__future = None # type: Optional[Future]
self.__state = self.State.Pending
self.__queue = None # type: Optional[TaskQueue]

pca_box = gui.vBox(self.controlArea, 'PCA Preprocessing')
self.apply_pca_cbx = gui.checkBox(
Expand Down Expand Up @@ -221,18 +227,17 @@ def _handle_exceptions(self, ex):

def cancel(self):
"""Cancel any running jobs."""
if self.__state == self.State.Running:
assert self.__future is not None
if self.__future is not None:
assert self.__queue is not None
self.__queue.cancel()
self.__queue = None
self.__future.cancel()
self.__future = None

self.__state = self.State.Pending

def commit(self):
self.Error.clear()
# Kill any running jobs
self.cancel()
assert self.__state == self.State.Pending

if self.data is None:
return
Expand Down Expand Up @@ -264,15 +269,17 @@ def commit(self):
queue.on_complete.connect(self._processing_complete)
queue.on_complete.connect(self._send_data)
queue.on_exception.connect(self._handle_exceptions)
self.__queue = queue

# Run the task queue
self.progressBarInit()
self.setBlocking(True)
self.__future = self.__executor.submit(queue.start)
self.__state = self.State.Running

def _send_data(self):
domain = self.data.domain
if self.partition is None:
return
# Compute the frequency of each cluster index
counts = np.bincount(self.partition)
indices = np.argsort(counts)[::-1]
Expand Down

0 comments on commit e5e3796

Please sign in to comment.