Skip to content

Commit

Permalink
VizRankDialog: Restrict frequency of signal emitting
Browse files Browse the repository at this point in the history
  • Loading branch information
VesnaT committed Sep 11, 2019
1 parent 3619455 commit b5aa2a2
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 4 deletions.
6 changes: 3 additions & 3 deletions Orange/widgets/visualize/tests/test_vizrankdialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def test_run_vizrank(self):
res_scores = sorted([compute_score(x) for x in states])
self.assertListEqual(res.scores, res_scores)
self.assertIsNot(scores, res.scores)
self.assertEqual(task.set_partial_result.call_count, 6)
self.assertEqual(task.set_partial_result.call_count, 2)
self.assertEqual(task.set_progress_value.call_count, 7)

def test_run_vizrank_interrupt(self):
Expand All @@ -59,7 +59,7 @@ def test_run_vizrank_interrupt(self):
res_scores = sorted([compute_score(x) for x in states[:2]])
self.assertListEqual(res.scores, res_scores)
self.assertIsNot(scores, res.scores)
self.assertEqual(task.set_partial_result.call_count, 2)
self.assertEqual(task.set_partial_result.call_count, 1)
self.assertEqual(task.set_progress_value.call_count, 3)
task.set_progress_value.assert_called_with(int(1 / 6 * 100))

Expand All @@ -76,7 +76,7 @@ def test_run_vizrank_interrupt(self):
res_scores = sorted([compute_score(x) for x in states])
self.assertListEqual(res.scores, res_scores)
self.assertIsNot(scores, res.scores)
self.assertEqual(task.set_partial_result.call_count, 6)
self.assertEqual(task.set_partial_result.call_count, 3)

This comment has been minimized.

Copy link
@markotoplak

markotoplak Sep 11, 2019

Member

I have a feeling these tests are going to crash... Now that you restrict the frequency the number of calls could differ on different computers.

This comment has been minimized.

Copy link
@VesnaT

VesnaT Sep 11, 2019

Author Contributor

The number of states is so small (all the scores are computed within a time period), the tests could actually work.

self.assertEqual(task.set_progress_value.call_count, 8)
task.set_progress_value.assert_called_with(int(5 / 6 * 100))

Expand Down
17 changes: 16 additions & 1 deletion Orange/widgets/visualize/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from queue import Queue, Empty
from types import SimpleNamespace as namespace
from typing import Optional, Iterable, List, Callable
from threading import Timer

from AnyQt.QtCore import Qt, QSize, pyqtSignal as Signal, QSortFilterProxyModel
from AnyQt.QtGui import QStandardItemModel, QStandardItem, QColor, QBrush, QPen
Expand Down Expand Up @@ -393,6 +394,7 @@ def run_vizrank(compute_score: Callable, iterate_states: Callable,
task.set_status("Getting scores...")
res = Result(queue=Queue(), scores=None)
scores = scores.copy()
can_set_partial_result = True

def do_work(st, next_st):
try:
Expand All @@ -405,7 +407,10 @@ def do_work(st, next_st):
except Exception: # ignore current state in case of any problem
pass
res.scores = scores.copy()
task.set_partial_result(res)

def reset_flag():
nonlocal can_set_partial_result
can_set_partial_result = True

state = None
next_state = next(states)
Expand All @@ -420,8 +425,18 @@ def do_work(st, next_st):
state = copy.copy(next_state)
next_state = copy.copy(next(states))
do_work(state, next_state)
# for simple scores (e.g. correlations widget) and many feature
# combinations, the 'partial_result_ready' signal (emitted by
# invoking 'task.set_partial_result') was emitted too frequently
# for a longer period of time and therefore causing the widget
# being unresponsive
if can_set_partial_result:
task.set_partial_result(res)
can_set_partial_result = False
Timer(0.01, reset_flag).start()
except StopIteration:
do_work(state, None)
task.set_partial_result(res)
return res


Expand Down

0 comments on commit b5aa2a2

Please sign in to comment.