diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py index 0d56141008..928d1ffdfb 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -17,9 +17,9 @@ from collections import defaultdict from collections.abc import MutableSet, Set from functools import partial, wraps from io import DEFAULT_BUFFER_SIZE, BytesIO -from threading import Lock -from time import time from queue import Queue +from threading import Lock +from time import sleep, time from calibre import as_unicode, isbytestring from calibre.constants import iswindows, preferred_encoding @@ -138,6 +138,7 @@ class Cache: was necessary for maximum performance and flexibility. ''' EventType = EventType + fts_indexing_sleep_time = 4 # seconds def __init__(self, backend): self.shutting_down = False @@ -512,6 +513,7 @@ class Cache: if self.backend.fts_enabled: import traceback traceback.print_exc() + sleep(self.fts_indexing_sleep_time) while not getattr(dbref(), 'shutting_down', True): x = queue.get() diff --git a/src/calibre/db/fts/pool.py b/src/calibre/db/fts/pool.py index 6e0893e06d..ae1a9b16cb 100644 --- a/src/calibre/db/fts/pool.py +++ b/src/calibre/db/fts/pool.py @@ -13,7 +13,6 @@ from threading import Event, Thread from time import monotonic from calibre import detect_ncpus, human_readable -from calibre.utils.config import dynamic from calibre.utils.ipc.simple_worker import start_pipe_worker check_for_work = object() @@ -117,13 +116,8 @@ class Worker(Thread): class Pool: - MAX_WORKERS_PREF_NAME = 'fts_pool_max_workers' - def __init__(self, dbref): - try: - self.max_workers = min(max(1, int(dynamic.get(self.MAX_WORKERS_PREF_NAME, 1))), detect_ncpus()) - except Exception: - self.max_workers = 1 + self.max_workers = 1 self.jobs_queue = Queue() self.supervise_queue = Queue() self.workers = [] @@ -170,7 +164,6 @@ class Pool: num = min(max(1, num), detect_ncpus()) if num != self.max_workers: self.max_workers = num - dynamic.set(self.MAX_WORKERS_PREF_NAME, num) if num > len(self.workers): self.expand_workers() elif num < len(self.workers): diff --git a/src/calibre/db/tests/fts_api.py b/src/calibre/db/tests/fts_api.py index 99a40ff5e7..e0279254c2 100644 --- a/src/calibre/db/tests/fts_api.py +++ b/src/calibre/db/tests/fts_api.py @@ -26,9 +26,9 @@ class FTSAPITest(BaseTest): def setUp(self): super().setUp() from calibre_extensions.sqlite_extension import set_ui_language - from calibre.db.fts.pool import Pool - self.orig_pw_pref_name = Pool.MAX_WORKERS_PREF_NAME - Pool.MAX_WORKERS_PREF_NAME = 'test_fts_max_workers' + from calibre.db.cache import Cache + self.orig_sleep_time = Cache.fts_indexing_sleep_time + Cache.fts_indexing_sleep_time = 0 set_ui_language('en') self.libraries_to_close = [] @@ -36,8 +36,8 @@ class FTSAPITest(BaseTest): [c.close() for c in self.libraries_to_close] super().tearDown() from calibre_extensions.sqlite_extension import set_ui_language - from calibre.db.fts.pool import Pool - Pool.MAX_WORKERS_PREF_NAME = self.orig_pw_pref_name + from calibre.db.cache import Cache + Cache.fts_indexing_sleep_time = self.orig_sleep_time set_ui_language('en') def new_library(self): diff --git a/src/calibre/gui2/fts/scan.py b/src/calibre/gui2/fts/scan.py index 1486eb7daa..46a81320e0 100644 --- a/src/calibre/gui2/fts/scan.py +++ b/src/calibre/gui2/fts/scan.py @@ -4,14 +4,14 @@ import os from qt.core import ( - QCheckBox, QDialog, QHBoxLayout, QLabel, QSpinBox, QTimer, QVBoxLayout, QWidget + QCheckBox, QDialog, QHBoxLayout, QLabel, QRadioButton, QTimer, QVBoxLayout, + QWidget ) from calibre import detect_ncpus -from calibre.db.fts.pool import Pool +from calibre.db.cache import Cache from calibre.gui2.dialogs.confirm_delete import confirm from calibre.gui2.fts.utils import get_db -from calibre.utils.config import dynamic class IndexingProgress: @@ -35,29 +35,28 @@ class ScanProgress(QWidget): l.addWidget(la) self.h = h = QHBoxLayout() l.addLayout(h) - self.niwl = la = QLabel(_('Number of workers used for indexing:')) - h.addWidget(la) - self.num_of_workers = n = QSpinBox(self) - n.setMinimum(1) - n.setMaximum(detect_ncpus()) - self.debounce_timer = t = QTimer(self) - t.setInterval(750) - t.timeout.connect(self.change_num_of_workers) - t.setSingleShot(True) - n.valueChanged.connect(self.schedule_change_num_of_workers) - try: - c = min(max(1, int(dynamic.get(Pool.MAX_WORKERS_PREF_NAME, 1))), n.maximum()) - except Exception: - c = 1 - n.setValue(c) - h.addWidget(n), h.addStretch(10) self.wl = la = QLabel(_( - 'Increasing the number of workers used for indexing will' - ' speed up indexing at the cost of using more of the computer\'s resources.' - ' Changes will take a few seconds to take effect.' + 'Normally, calibre indexes books slowly in the background,' + ' to avoid overloading your computer. You can instead ask' + ' calibre to speed up indexing, if you intend to leave your' + ' computer running overnight or similar to quickly finish the indexing.' + ' Doing so will likely make both calibre and your computer less responsive,' + ' while the fast indexing is running.' )) la.setWordWrap(True) l.addWidget(la) + self.h = h = QHBoxLayout() + l.addLayout(h) + h.addWidget(QLabel(_('Indexing speed:'))) + self.slow_button = sb = QRadioButton(_('&Slow'), self) + sb.setChecked(True) + h.addWidget(sb) + self.fast_button = fb = QRadioButton(_('&Fast'), self) + h.addWidget(fb) + fb.toggled.connect(self.change_speed) + h.addStretch(10) + + l.addStretch(10) self.warn_label = la = QLabel('

{}: {}'.format( _('WARNING'), _( 'Not all the books in this library have been indexed yet.' @@ -65,12 +64,14 @@ class ScanProgress(QWidget): la.setWordWrap(True) l.addWidget(la) - def schedule_change_num_of_workers(self): - self.debounce_timer.stop() - self.debounce_timer.start() - - def change_num_of_workers(self): - get_db().set_fts_num_of_workers(self.num_of_workers.value()) + def change_speed(self): + db = get_db() + if self.fast_button.isChecked(): + db.fts_indexing_sleep_time = 0.1 + db.set_fts_num_of_workers(max(1, detect_ncpus())) + else: + db.fts_indexing_sleep_time = Cache.fts_indexing_sleep_time + db.set_fts_num_of_workers(1) def update(self, indexing_progress): if indexing_progress.complete: @@ -141,6 +142,7 @@ class ScanStatus(QWidget): def shutdown(self): self.indexing_status_timer.stop() + self.scan_progress.slow_button.setChecked(True) if __name__ == '__main__':