Skip to content

ProcessPoolExecutor fails to notify when called with shutdown(cancel_futures=True) #136655

Description

@chrisvanrun

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytopic-multiprocessingtype-bugAn unexpected behavior, bug, or error

    Projects

    Status
    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions