From 0f38514ad705aa42cbe02276cd5929e0be6cf139 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Fri, 6 Mar 2020 13:21:24 +1000 Subject: [PATCH] drop the DB progress handler code This code was an awful hack to provide some semblance of UI responsiveness while executing DB statements on the main thread. Instead, we can just run DB statements in a background thread now, keeping the UI responsive. --- pylib/anki/dbproxy.py | 4 ---- qt/aqt/browser.py | 3 --- qt/aqt/main.py | 2 -- qt/aqt/progress.py | 43 ++++++------------------------------------- 4 files changed, 6 insertions(+), 46 deletions(-) diff --git a/pylib/anki/dbproxy.py b/pylib/anki/dbproxy.py index ae6136ace..5b6fa0bbf 100644 --- a/pylib/anki/dbproxy.py +++ b/pylib/anki/dbproxy.py @@ -9,10 +9,6 @@ import anki # fixme: col.close()/col.reopen() & journal_mode=delete -# fixme: setAutocommit() -# fixme: transaction/lock handling -# fixme: progress - # DBValue is actually Union[str, int, float, None], but if defined # that way, every call site needs to do a type check prior to using # the return values. diff --git a/qt/aqt/browser.py b/qt/aqt/browser.py index eb74e3f73..2760bec79 100644 --- a/qt/aqt/browser.py +++ b/qt/aqt/browser.py @@ -391,15 +391,12 @@ class StatusDelegate(QItemDelegate): self.model = model def paint(self, painter, option, index): - self.browser.mw.progress.blockUpdates = True try: c = self.model.getCard(index) except: # in the the middle of a reset; return nothing so this row is not # rendered until we have a chance to reset the model return - finally: - self.browser.mw.progress.blockUpdates = True if self.model.isRTL(index): option.direction = Qt.RightToLeft diff --git a/qt/aqt/main.py b/qt/aqt/main.py index ecf841f2b..dd3ab2566 100644 --- a/qt/aqt/main.py +++ b/qt/aqt/main.py @@ -463,7 +463,6 @@ close the profile or restart Anki.""" self.col = Collection(cpath) self.setEnabled(True) - self.progress.setupDB(self.col.db) self.maybeEnableUndo() self.moveToState("deckBrowser") return True @@ -1531,7 +1530,6 @@ Please ensure a profile is open and Anki is not busy, then try again.""" gc.disable() def doGC(self) -> None: - assert not self.progress.inDB gc.collect() # Crash log diff --git a/qt/aqt/progress.py b/qt/aqt/progress.py index de8b9aef5..cc8852299 100644 --- a/qt/aqt/progress.py +++ b/qt/aqt/progress.py @@ -11,10 +11,6 @@ import aqt.forms from anki.lang import _ from aqt.qt import * -# fixme: if mw->subwindow opens a progress dialog with mw as the parent, mw -# gets raised on finish on compiz. perhaps we should be using the progress -# dialog as the parent? - # Progress info ########################################################################## @@ -29,44 +25,14 @@ class ProgressManager: self._win = None self._levels = 0 - # SQLite progress handler - ########################################################################## - - def setupDB(self, db): - "Install a handler in the current DB." - self.lastDbProgress = 0 - self.inDB = False - # db.set_progress_handler(self._dbProgress, 10000) - - def _dbProgress(self): - "Called from SQLite." - # do nothing if we don't have a progress window - if not self._win: - return - # make sure we're not executing too frequently - if (time.time() - self.lastDbProgress) < 0.01: - return - self.lastDbProgress = time.time() - # and we're in the main thread - if not self.mw.inMainThread(): - return - # ensure timers don't fire - self.inDB = True - # handle GUI events - if not self.blockUpdates: - self._maybeShow() - self.app.processEvents(QEventLoop.ExcludeUserInputEvents) - self.inDB = False - # Safer timers ########################################################################## - # QTimer may fire in processEvents(). We provide a custom timer which - # automatically defers until the DB is not busy, and avoids running - # while a progress window is visible. + # A custom timer which avoids firing while a progress dialog is active + # (likely due to some long-running DB operation) def timer(self, ms, func, repeat, requiresCollection=True): def handler(): - if self.inDB or self._levels: + if self._levels: # retry in 100ms self.timer(100, func, False, requiresCollection) elif not self.mw.col and requiresCollection: @@ -123,6 +89,9 @@ class ProgressManager: def update(self, label=None, value=None, process=True, maybeShow=True): # print self._min, self._counter, self._max, label, time.time() - self._lastTime + if not self.mw.inMainThread(): + print("progress.update() called on wrong thread") + return if self._updating: return if maybeShow: