`ProcessPoolExecutor` fails to notify when called with `shutdown(cancel_futures=True)`
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Python
- Estrellas
- 77.2k
- Forks
- 35.9k
- Métricas de merge de PR
- Métricas de PR pendientes
Descripción
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
import concurrent.futures
import time
def task(n: int) -> int:
if n == 2:
raise Exception("Not gonna do it")
else:
time.sleep(0.1)
return n
def main() -> None:
with concurrent.futures.ProcessPoolExecutor(
max_workers=2,
) as executor:
futures = [executor.submit(task, i) for i in range(1, 16)]
for future in concurrent.futures.as_completed(futures):
try:
result = future.result()
except Exception as e:
print(f"Exception: {e}")
executor.shutdown(wait=False, cancel_futures=True)
continue
print(f"Result: {result}")
# Look for 'CANCELLED' here:
print("Other futures states:", [f._state for f in futures])
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
One could replace it with:
for work_id, work_item in self.pending_work_items.items():
canceled = work_item.future.cancel()
if canceled:
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
- gh-140021
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Comienza en Lib/concurrent/futures/process.py alrededor de las líneas 520–522 y reproduce el bloqueo con el ejemplo mínimo de ProcessPoolExecutor. Compara el comportamiento propuesto con PR 134618 y verifica después que shutdown(cancel_futures=True) notifica a los futures cancelados para que as_completed no se bloquee.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- python
- Área
- backend
- Tipo de issue
- Error
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Estado de actividad
- Estancado
- Claridad
- Bastante claro
- Aptitud para principiantes
- 38/100