Bug report
Bug description:
I am running a small processor that handles large tasks. When a task encounters an exception I want to store all errors (including other tasks errors) and cancel any other queued work.
However, it seems like the ProcessPoolExecutor's _ExecutorManagerThread does not notify any waiting threads of the future cancelations: making the idiom as_completed hang indefinitely.
Minimal Reproducable Example
importconcurrent.futuresimporttimedeftask(n: int) ->int:
ifn==2:
raiseException("Not gonna do it")
else:
time.sleep(0.1)
returnndefmain() ->None:
withconcurrent.futures.ProcessPoolExecutor(
max_workers=2,
) asexecutor:
futures= [executor.submit(task, i) foriinrange(1, 16)]
forfutureinconcurrent.futures.as_completed(futures):
try:
result=future.result()
exceptExceptionase:
print(f"Exception: {e}")
executor.shutdown(wait=False, cancel_futures=True)
continueprint(f"Result: {result}")
# Look for 'CANCELLED' here:print("Other futures states:", [f._stateforfinfutures])
if__name__=="__main__":
main()Workaround
A workaround is to break after the first future that completed with a failure and do a post hoc gathering of other exceptions of non-cancelled futures.
Suggested Fix
In
| forwork_id, work_iteminself.pending_work_items.items(): |
| ifnotwork_item.future.cancel(): |
| new_pending_work_items[work_id] =work_item |
One could replace it with:
forwork_id, work_iteminself.pending_work_items.items():
canceled=work_item.future.cancel()
ifcanceled:
work_item.future.set_running_or_notify_cancel()
else:
new_pending_work_items[work_id] =work_item
Similar like:
CPython versions tested on:
3.13
Operating systems tested on:
macOS
Linked PRs
Bug report
Bug description:
I am running a small processor that handles large tasks. When a task encounters an exception I want to store all errors (including other tasks errors) and cancel any other queued work.
However, it seems like the ProcessPoolExecutor's
_ExecutorManagerThreaddoes not notify any waiting threads of the future cancelations: making the idiomas_completedhang indefinitely.Minimal Reproducable Example
Workaround
A workaround is to break after the first future that completed with a failure and do a post hoc gathering of other exceptions of non-cancelled futures.
Suggested Fix
In
cpython/Lib/concurrent/futures/process.py
Lines 520 to 522 in a68ddea
One could replace it with:
Similar like:
CPython versions tested on:
3.13
Operating systems tested on:
macOS
Linked PRs