Memory leak: the shared `validation_aborted_error` keeps every traceback it is raised through
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 78/100
Línea de trabajo
Empieza en graphql/validation/validate.py, donde se lanza el validation_aborted_error compartido, y revisa cómo validate() gestiona el momento en que se alcanza max_errors. La reproducción del issue muestra el traceback y el crecimiento de memoria; ejecútala antes y después del cambio para confirmar que las llamadas repetidas ya no retienen tracebacks cada vez mayores. Se considera terminado cuando cada llamada de validación lanza su propio error y el crecimiento de memoria se estabiliza.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Since aab6d50 (first released in 3.3.0a3), validate() raises one shared, module-level ValidationAbortedError once max_errors is reached. When an existing exception object is raised again, Python adds the new frames to its existing __traceback__. So every aborted validation lengthens the singleton's traceback, and that traceback keeps those frames, and with them each request's document and validation context, alive for the life of the process.
Any client can trigger this by sending a query with more than 100 validation errors. In a long-running server, memory grows with every such request.
Reproduction (graphql-core 3.3.0, CPython 3.12):
import gc, tracemalloc
from graphql import build_schema, parse, validate
from graphql.validation.validate import validation_aborted_error
schema = build_schema("type Query { a: Int }")
document = parse("{ " + " ".join(f"f{i}" for i in range(101)) + " }")
tracemalloc.start()
validate(schema, document)
gc.collect()
base = tracemalloc.get_traced_memory()[0]
for _ in range(200):
validate(schema, document)
gc.collect()
tb, n = validation_aborted_error.__traceback__, 0
while tb:
n, tb = n + 1, tb.tb_next
print(n, (tracemalloc.get_traced_memory()[0] - base) // 1024, "KiB")
Result:
| Repeated calls | Traceback entries | Memory retained |
|---|---|---|
| 1 | 16 | 147 KiB |
| 10 | 88 | 1,389 KiB |
| 100 | 808 | 12,549 KiB |
| 200 | 1,608 | 24,820 KiB |
That is about 124 KiB more per aborted validation, with no upper limit. The same script on 3.2.13, which creates a new error each time, levels off at about 259 KiB.
Suggested fix: create a new ValidationAbortedError on each validate() call instead of reusing the module-level instance. Clearing __traceback__ before each raise would also work, but every caller's error list would still share one mutable error object.
- Lenguaje dominante
- Python
- Estrellas
- 532
- Forks
- 154
- Merge medio
- 1 d 9 h
- PR fusionados (30 d)
- 6
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Sin 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.
Más de graphql-python/graphql-core
-
`collect_subfields` memoization keyed on `id()` of `FieldDetails` that are not kept alive returns another field's subfieldsPosiblemente ocupada @jadenfix la tomó hace 5 días. Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 72/100
graphql-python/graphql-core#284 · 1 comentario ·
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 35/100
graphql-python/graphql-core#278 ·
-
Dificultad 3/5 1-2 días Aptitud para principiantes 45/100
graphql-python/graphql-core#257 ·
-
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
graphql-python/graphql-core#223 · 1 comentario ·
-
documentation good first issue
Dificultad 2/5 1-3 horas Aptitud para principiantes 35/100
graphql-python/graphql-core#220 · 4 comentarios ·
Todos los issues de graphql-python/graphql-core
Issues similares
-
Dificultad 1/5 1-3 horas Aptitud para principiantes 85/100
WLAN-Pi/wlanpi-profiler#341 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 67/100
roman-corgi/ctc-dip#160 ·
Los mantenedores suelen responder en 1 día
-
type-bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día
-
render_findings.py reads and writes in the host's default encoding, so findings.html breaks on a cp1252 Windows hostPosiblemente ocupada @Aaqibhafeezkhan la tomó hoy. Abiertobug good first issue mentored python size: XS up-for-grabs
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
dheerajjha/mcp-migrate#366 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día