Dont use a timer for indexing progress

This makes things very slow as it requires locking the database ever
second. Instead use the db's event system to deliver indexing progress
changed events.
This commit is contained in:
Kovid Goyal 2022-06-15 14:18:13 +05:30
parent e747fddf0d
commit 152145e1ad
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 38 additions and 15 deletions

View File

@ -431,6 +431,7 @@ class Cache:
def initialize_fts(self):
self.fts_queue_thread = None
self.fts_job_queue = Queue()
self.fts_indexing_left = self.fts_indexing_total = 0
fts = self.backend.initialize_fts(weakref.ref(self))
if self.is_fts_enabled():
self.start_fts_pool()
@ -448,14 +449,20 @@ class Cache:
def is_fts_enabled(self):
return self.backend.fts_enabled
@read_api
@api
def fts_indexing_progress(self):
if not self.is_fts_enabled():
return 0, 0
num_to_scan = self.backend.fts.number_dirtied()
if not num_to_scan:
return 0, 1
return num_to_scan, (self.backend.get('SELECT COUNT(*) FROM main.data')[0][0] or 0)
return self.fts_indexing_left, self.fts_indexing_total
def _update_fts_indexing_numbers(self):
# this is called when new formats are added and when a format is
# indexed, but NOT when books or formats are deleted, so total may not
# be up to date.
nl = self.backend.fts.number_dirtied()
nt = self.backend.get('SELECT COUNT(*) FROM main.data')[0][0] or 0
if (self.fts_indexing_left, self.fts_indexing_total) != (nl, nt):
self.fts_indexing_left = nl
self.fts_indexing_total = nt
self.event_dispatcher(EventType.indexing_progress_changed, nl, nt)
@write_api
def enable_fts(self, enabled=True, start_pool=True):
@ -527,10 +534,13 @@ class Cache:
if not self.backend.fts_enabled:
return
self.fts_job_queue.put(True)
self._update_fts_indexing_numbers()
@write_api
def commit_fts_result(self, book_id, fmt, fmt_size, fmt_hash, text, err_msg):
return self.backend.commit_fts_result(book_id, fmt, fmt_size, fmt_hash, text, err_msg)
ans = self.backend.commit_fts_result(book_id, fmt, fmt_size, fmt_hash, text, err_msg)
self._update_fts_indexing_numbers()
return ans
@api
def reindex_fts(self):

View File

@ -40,6 +40,9 @@ class EventType(Enum):
#: When a book format is edited, with arguments: (book_id, fmt)
book_edited = auto()
#: When the indexing progress changes
indexing_progress_changed = auto()
class EventDispatcher(Thread):

View File

@ -5,13 +5,15 @@
import os
from qt.core import (
QCheckBox, QDialog, QDialogButtonBox, QHBoxLayout, QIcon, QLabel, QPushButton,
QRadioButton, QTimer, QVBoxLayout, QWidget, pyqtSignal
QRadioButton, QVBoxLayout, QWidget, pyqtSignal
)
from calibre import detect_ncpus
from calibre.db.cache import Cache
from calibre.db.listeners import EventType
from calibre.gui2.dialogs.confirm_delete import confirm
from calibre.gui2.fts.utils import get_db
from calibre.gui2.ui import get_gui
class IndexingProgress:
@ -139,11 +141,20 @@ class ScanStatus(QWidget):
l.addStretch(10)
self.apply_fts_state()
self.enable_fts.toggled.connect(self.change_fts_state)
self.indexing_status_timer = t = QTimer(self)
t.timeout.connect(self.update_stats)
t.setInterval(1000)
t.start()
self.update_stats()
gui = get_gui()
if gui is None:
self.db.add_listener(self)
else:
gui.add_db_listener(self.gui_update_event)
def gui_update_event(self, db, event_type, event_data):
if event_type is EventType.indexing_progress_changed:
self.update_stats()
def __call__(self, event_type, library_id, event_data):
if event_type is EventType.indexing_progress_changed:
self.update_stats()
def update_stats(self):
changed = self.indexing_progress.update(*self.db.fts_indexing_progress())
@ -200,10 +211,9 @@ class ScanStatus(QWidget):
self.apply_fts_state()
def startup(self):
self.indexing_status_timer.start()
pass
def shutdown(self):
self.indexing_status_timer.stop()
self.scan_progress.slow_button.setChecked(True)
self.reset_indexing_state_for_current_db()