cancel_all.py (1940B)
1 # This Source Code Form is subject to the terms of the Mozilla Public 2 # License, v. 2.0. If a copy of the MPL was not distributed with this 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5 6 import logging 7 import os 8 from concurrent import futures 9 10 from taskcluster.exceptions import TaskclusterRestFailure 11 from taskgraph.util.taskcluster import CONCURRENCY, cancel_task 12 13 from gecko_taskgraph.util.taskcluster import list_task_group_incomplete_task_ids 14 15 from .registry import register_callback_action 16 17 logger = logging.getLogger(__name__) 18 19 20 @register_callback_action( 21 title="Cancel All", 22 name="cancel-all", 23 symbol="cAll", 24 description=( 25 "Cancel all running and pending tasks created by the decision task " 26 "this action task is associated with." 27 ), 28 order=400, 29 context=[], 30 ) 31 def cancel_all_action(parameters, graph_config, input, task_group_id, task_id): 32 def do_cancel_task(task_id): 33 logger.info(f"Cancelling task {task_id}") 34 try: 35 cancel_task(task_id) 36 except TaskclusterRestFailure as e: 37 if e.status_code == 409: 38 # A 409 response indicates that this task is past its deadline. It 39 # cannot be cancelled at this time, but it's also not running 40 # anymore, so we can ignore this error. 41 logger.info( 42 f"Task {task_id} is past its deadline and cannot be cancelled." 43 ) 44 return 45 raise 46 47 own_task_id = os.environ.get("TASK_ID", "") 48 to_cancel = [ 49 t 50 for t in list_task_group_incomplete_task_ids(task_group_id) 51 if t != own_task_id 52 ] 53 54 logger.info(f"Cancelling {len(to_cancel)} tasks") 55 with futures.ThreadPoolExecutor(CONCURRENCY) as e: 56 cancel_futs = [e.submit(do_cancel_task, t) for t in to_cancel] 57 for f in futures.as_completed(cancel_futs): 58 f.result()