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.
This commit is contained in:
Damien Elmes 2020-03-06 13:21:24 +10:00
parent 90d4d62c48
commit 0f38514ad7
4 changed files with 6 additions and 46 deletions

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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: