jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/807423 )
Change subject: [bugfix] Handle page_put_queue after KeyboardInterrupt ......................................................................
[bugfix] Handle page_put_queue after KeyboardInterrupt
With Python 3.9+ the _putthread thread is stopped and cannot be continued.
- Handle the page_put_queue after KeyboardInterrupt - stop the queue if _flush is not called during atexit
Bug: T311076 Change-Id: Id7c07562e46c5e7b411e386d76ba23f4125ad0ff --- M pywikibot/__init__.py 1 file changed, 25 insertions(+), 18 deletions(-)
Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py index 3264486..8954930 100644 --- a/pywikibot/__init__.py +++ b/pywikibot/__init__.py @@ -1319,23 +1319,30 @@ 'Estimated time remaining: {sec}<<default>>' .format(num=num, sec=sec))
+ exit_queue = None if _putthread is not threading.current_thread(): - while (_putthread.is_alive() - and (page_put_queue.qsize() > 0 - or page_put_queue_busy.qsize() > 0)): + while _putthread.is_alive() and not (page_put_queue.empty() + and page_put_queue_busy.empty()): try: _putthread.join(1) except KeyboardInterrupt: - if input_yn('There are {} pages remaining in the queue. ' - 'Estimated time remaining: {}\nReally exit?' - .format(*remaining()), - default=False, automatic_quit=False): - # delete the put queue - with page_put_queue.mutex: - page_put_queue.all_tasks_done.notify_all() - page_put_queue.queue.clear() - page_put_queue.not_full.notify_all() - break + exit_queue = input_yn( + 'There are {} pages remaining in the queue. Estimated ' + 'time remaining: {}\nReally exit?'.format(*remaining()), + default=False, automatic_quit=False) + break + + if exit_queue is False: + # handle the queue when _putthread is stopped after KeyboardInterrupt + with suppress(KeyboardInterrupt): + async_manager(block=False) + + if not stop: + # delete the put queue + with page_put_queue.mutex: + page_put_queue.all_tasks_done.notify_all() + page_put_queue.queue.clear() + page_put_queue.not_full.notify_all()
# only need one drop() call because all throttles use the same global pid with suppress(IndexError): @@ -1343,14 +1350,13 @@ log('Dropped throttle(s).')
-atexit.register(_flush) - - # Create a separate thread for asynchronous page saves (and other requests) -def async_manager() -> None: +def async_manager(block=True) -> None: """Daemon; take requests from the queue and execute them in background.""" while True: - (request, args, kwargs) = page_put_queue.get() + if not block and page_put_queue.empty(): + break + (request, args, kwargs) = page_put_queue.get(block) page_put_queue_busy.put(None) if request is None: break @@ -1375,3 +1381,4 @@ _putthread = threading.Thread(target=async_manager, name='Put-Thread', # for debugging purposes daemon=True) +atexit.register(_flush)
pywikibot-commits@lists.wikimedia.org