python / python/cpython

concurrent.futures.wait() waits forever if given a cancelled future

Abierto
#92,001 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

topic-multiprocessing type-bug
Lenguaje dominante
Python
Estrellas
77.2k
Forks
36k
Merge medio
1 d 9 h
PR fusionados (30 d)
558

Descripción

Bug report

concurrent.futures.wait() hangs if given a future that is already cancelled.

Steps to reproduce:

  1. Get a future that is cancellable (create lots of jobs such that the later ones cannot start yet and are therefore cancellable):
>>> import concurrent.futures
>>> pool = concurrent.futures.ThreadPoolExecutor(max_workers=1)
>>> import time
>>> for _ in range(1000): future = pool.submit(time.sleep, 1000)
  1. Cancel this future and note that it returns True meaning it has been cancelled.
>>> future.cancel()
True
  1. Now waiting on this future hangs:
>>> concurrent.futures.wait([future]) 

The expected behaviour, regardless of the value of return_when is that wait() treats cancelled futures as already completed. This is essentially how return_when=FIRST_COMPLETED and return_when=ALL_COMPLETED are documented to behave:

The function will return when any future finishes or is cancelled.

and

The function will return when all futures finish or are cancelled.

Treating a future that is cancelled prior to wait() as different to one that changes state to cancelled once waiting risks a race condition: it could change state after any possible check but before blocking. i.e. it needs to be level-triggered not edge-triggered. And indeed, it works this way for futures that are done, just not ones that are cancelled.

Your environment

  • CPython versions tested on: 3.9.7, 3.10.2
  • Operating system and architecture: Linux

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza reproduciendo el ejemplo proporcionado con concurrent.futures.wait() y un future ya cancelado. Inspecciona el punto de entrada wait() y su gestión de futures cancelados; después, añade cobertura para el comportamiento informado. Se considera terminado cuando wait() retorna en lugar de quedarse bloqueado para los valores documentados de return_when.

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
Bien especificado
Aptitud para principiantes
52/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.