improve thread stability

This commit is contained in:
St.Huang 2018-07-02 01:18:00 +08:00
parent b44d1f4bf5
commit 70b5f73308

View File

@ -31,7 +31,7 @@ from aqt.utils import showInfo, showText, tooltip
from .constants import Endpoint, Template from .constants import Endpoint, Template
from .context import config from .context import config
from .lang import _, _sl from .lang import _, _sl
from .progress import ProgressManager from .progress import ProgressWindow
from .service import service_manager, QueryResult, copy_static_file from .service import service_manager, QueryResult, copy_static_file
from .utils import Empty, MapDict, Queue, wrap_css from .utils import Empty, MapDict, Queue, wrap_css
@ -66,8 +66,7 @@ class QueryThread(QThread):
""" """
Query Worker Thread Query Worker Thread
""" """
progress_update = pyqtSignal(dict)
note_flush = pyqtSignal(object) note_flush = pyqtSignal(object)
def __init__(self, manager): def __init__(self, manager):
@ -75,12 +74,11 @@ class QueryThread(QThread):
self.index = 0 self.index = 0
self.exit = False self.exit = False
self.manager = manager self.manager = manager
self.progress_update.connect(progress.update_labels) self.note_flush.connect(manager.handle_flush)
self.note_flush.connect(handle_flush)
def run(self): def run(self):
while True: while True:
if progress.abort() or self.exit or self.manager == None: if self.exit or not self.manager:
break break
try: try:
note = self.manager.queue.get(True, timeout=0.1) note = self.manager.queue.get(True, timeout=0.1)
@ -90,20 +88,14 @@ class QueryThread(QThread):
try: try:
results, success_num = query_all_flds(note) results, success_num = query_all_flds(note)
if self.manager: if not self.exit and self.manager:
if self.manager.update(note, results, success_num): if self.manager.update(note, results, success_num):
self.note_flush.emit(note) self.note_flush.emit(note)
# Update progress window infomation
self.progress_update.emit(
MapDict(
type='count',
words_number = self.manager.counter,
fails_number = self.manager.fails,
fields_number = self.manager.fields)
)
except InvalidWordException: except InvalidWordException:
showInfo(_("NO_QUERY_WORD")) showInfo(_("NO_QUERY_WORD"))
if self.manager:
self.manager.queue.task_done()
class QueryWorkerManager(object): class QueryWorkerManager(object):
@ -115,8 +107,10 @@ class QueryWorkerManager(object):
self.workers = [] self.workers = []
self.queue = Queue() self.queue = Queue()
self.mutex = QMutex() self.mutex = QMutex()
self.progress = ProgressWindow(mw)
self.total = 0 self.total = 0
self.counter = 0 self.counter = 0
self.fails = 0
self.fields = 0 self.fields = 0
def get_worker(self): def get_worker(self):
@ -126,29 +120,13 @@ class QueryWorkerManager(object):
return worker return worker
def start(self): def start(self):
for x in range(0, min(config.thread_number, self.queue.qsize())): self.total = self.queue.qsize()
self.progress.start(self.total, min=0)
for x in range(0, min(config.thread_number, self.total)):
self.get_worker() self.get_worker()
self.total = self.queue.qsize()
for worker in self.workers: for worker in self.workers:
worker.start() worker.start()
def reset(self):
for worker in self.workers:
worker.exit = True
worker.manager = None
worker.terminate()
self.mutex.unlock()
self.workers = []
self.queue = Queue()
self.total = 0
self.counter = 0
self.fails = 0
self.fields = 0
def clean(self):
self.reset()
def update(self, note, results, success_num): def update(self, note, results, success_num):
self.mutex.lock() self.mutex.lock()
@ -164,16 +142,23 @@ class QueryWorkerManager(object):
def join(self): def join(self):
for worker in self.workers: for worker in self.workers:
while not worker.isFinished(): while not worker.isFinished():
if progress.abort(): if self.progress.abort():
worker.exit = True
break break
else:
self.progress.update_labels(MapDict(
type='count',
words_number = self.counter,
fails_number = self.fails,
fields_number = self.fields))
mw.app.processEvents() mw.app.processEvents()
worker.wait(100) worker.wait(100)
self.progress.finish()
@pyqtSlot(object) @pyqtSlot(object)
def handle_flush(note): def handle_flush(self, note):
if note: if note:
note.flush() note.flush()
def query_from_browser(browser): def query_from_browser(browser):
@ -192,7 +177,7 @@ def query_from_browser(browser):
return return
query_all(notes) query_all(notes)
browser.model.reset() # browser.model.reset()
def query_from_editor_all_fields(editor): def query_from_editor_all_fields(editor):
@ -204,7 +189,7 @@ def query_from_editor_all_fields(editor):
return return
query_all([editor.note]) query_all([editor.note])
editor.setNote(editor.note, focus=True) #editor.setNote(editor.note, focus=True)
editor.saveNow() editor.saveNow()
@ -216,8 +201,9 @@ def query_all(notes):
if len(notes) == 0: if len(notes) == 0:
return return
work_manager.reset() work_manager = QueryWorkerManager()
progress.start(max=len(notes), min=0, immediate=True) #work_manager.reset()
#progress.start(max=len(notes), min=0, immediate=True)
queue = work_manager.queue queue = work_manager.queue
for i, note in enumerate(notes): for i, note in enumerate(notes):
@ -226,11 +212,11 @@ def query_all(notes):
work_manager.start() work_manager.start()
work_manager.join() work_manager.join()
progress.finish() #progress.finish()
promot_choose_css() promot_choose_css()
tooltip(u'{0} {1} {2}, {3} {4}'.format(_('UPDATED'), work_manager.counter, _('CARDS'), work_manager.fields, _('FIELDS'))) tooltip(u'{0} {1} {2}, {3} {4}'.format(_('UPDATED'), work_manager.counter, _('CARDS'), work_manager.fields, _('FIELDS')))
work_manager.clean() #work_manager.clean()
service_pool.clean(); service_pool.clean()
def update_note_fields(note, results): def update_note_fields(note, results):
@ -322,7 +308,7 @@ def query_all_flds(note):
if not word: if not word:
raise InvalidWordException raise InvalidWordException
progress.update_title(u'Querying [[ %s ]]' % word) # progress.update_title(u'Querying [[ %s ]]' % word)
services = {} services = {}
tasks = [] tasks = []
@ -387,8 +373,6 @@ class ServicePool(object):
def clean(self): def clean(self):
self.pools = {} self.pools = {}
progress = ProgressManager(mw) # progress window
work_manager = QueryWorkerManager() # Query Worker Thread Manager
service_pool = ServicePool() # Service Instance Pool Manager service_pool = ServicePool() # Service Instance Pool Manager