jenkins-bot has submitted this change. ( 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/904245 )

Change subject: [IMPR] enable KeyboardInterrupt with -async option
......................................................................

[IMPR] enable KeyboardInterrupt with -async option

Change-Id: I021005b9c7c80e5ef6a14ef5246d006596333ddb
---
M scripts/archivebot.py
1 file changed, 54 insertions(+), 10 deletions(-)

Approvals:
  Xqt: Looks good to me, approved
  jenkins-bot: Verified




diff --git a/scripts/archivebot.py b/scripts/archivebot.py
index a530410..ca1aac9 100755
--- a/scripts/archivebot.py
+++ b/scripts/archivebot.py
@@ -105,15 +105,16 @@
   -keep           Preserve thread order in archive even if threads are
                   archived later
   -sort           Sort archive by timestamp; should not be used with -keep
-  -async          Run the bot in parallel tasks. This is experimental
-                  and the bot cannot be stopped with KeyboardInterrupt
+  -async          Run the bot in parallel tasks.

 .. versionchanged:: 7.6
    Localized variables for "archive" template parameter are supported.
    `User:MiszaBot/config` is the default template. `-keep` option was
    added.
 .. versionchanged:: 7.7
-   `-sort` and `-async` options were added.
+   ``-sort`` and ``-async`` options were added.
+.. versionchanged:: 8.2
+   KeyboardInterrupt was enabled with ``-async`` option.
 """
 #
 # (C) Pywikibot team, 2006-2023
@@ -124,13 +125,15 @@
 import locale
 import os
 import re
+import signal
+import threading
 import time
 from collections import OrderedDict, defaultdict
 from concurrent.futures import ThreadPoolExecutor
 from hashlib import md5
 from math import ceil
 from textwrap import fill
-from typing import Any, Optional, Pattern
+from typing import Any, Optional, Pattern, Union
 from warnings import warn

 import pywikibot
@@ -145,6 +148,7 @@
     to_local_digits,
 )
 from pywikibot.time import MW_KEYS, parse_duration, str2timedelta
+from pywikibot.tools import PYTHON_VERSION


 ShouldArchive = Tuple[str, str]
@@ -877,6 +881,11 @@

     :param args: command line arguments
     """
+    def signal_handler(signum, frame):
+        pywikibot.info('\n<<lightyellow>>User quit bot run...')
+        exiting.set()
+
+    exiting = threading.Event()
     filename = None
     pagename = None
     namespace = None
@@ -885,7 +894,7 @@
     calc = None
     keep = False
     sort = False
-    asyncronous = False
+    asynchronous = False
     templates = []

     local_args = pywikibot.handle_args(args)
@@ -920,7 +929,7 @@
         elif option == 'sort':
             sort = True
         elif option == 'async':
-            asyncronous = True
+            asynchronous = True

     site = pywikibot.Site()

@@ -932,6 +941,12 @@
         pywikibot.info('No template was specified, using default {{{{{}}}}}.'
                        .format(templates[0]))

+    if asynchronous:
+        signal.signal(signal.SIGINT, signal_handler)
+        context = ThreadPoolExecutor
+    else:
+        context = nullcontext
+
     for template_name in templates:
         tmpl = pywikibot.Page(site, template_name, ns=10)
         if filename:
@@ -949,13 +964,33 @@
                                      content=True)

         botargs = tmpl, salt, force, keep, sort
-        context = ThreadPoolExecutor if asyncronous else nullcontext
+        futures = []  # needed for Python < 3.9
         with context() as executor:
             for pg in gen:
-                if asyncronous:
-                    executor.submit(process_page, pg, *botargs)
+                if asynchronous:
+                    future = executor.submit(process_page, pg, *botargs)
+
+                    if PYTHON_VERSION < (3, 9):
+                        futures.append(future)
+
+                    if not exiting.is_set():
+                        continue
+
+                    canceled: Union[str, int] = ''
+                    pywikibot.info(
+                        '<<lightyellow>>Canceling pending Futures... ',
+                        newline=False)
+
+                    if PYTHON_VERSION < (3, 9):
+                        canceled = sum(future.cancel() for future in futures)
+                    else:
+                        executor.shutdown(cancel_futures=True)
+
+                    pywikibot.info(f'{canceled} done')
+                    break
+
                 elif not process_page(pg, *botargs):
-                    return
+                    break


 if __name__ == '__main__':

--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/904245
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.wikimedia.org/r/settings

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I021005b9c7c80e5ef6a14ef5246d006596333ddb
Gerrit-Change-Number: 904245
Gerrit-PatchSet: 6
Gerrit-Owner: Xqt <[email protected]>
Gerrit-Reviewer: D3r1ck01 <[email protected]>
Gerrit-Reviewer: Legoktm <[email protected]>
Gerrit-Reviewer: Xqt <[email protected]>
Gerrit-Reviewer: jenkins-bot
Gerrit-CC: MarcoAurelio <[email protected]>
Gerrit-CC: Matěj Suchánek <[email protected]>
Gerrit-MessageType: merged
_______________________________________________
Pywikibot-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to