Queued log transport should detect (and ideally survive) fork/snapshot-restore without consumer intervention
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 48/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bastante claro
- Estado de actividad
- Tranquilo
- Stack tecnológico
- python
- Área
- backend, observability
Línea de trabajo
Empieza leyendo destinations/queued.py y luego sigue restart_log_destinations() y restart_observability(), incluido el orden posterior a la restauración en el lado del consumidor descrito en PolicyEngine/policyengine-household-api#1597. Revisa la ruta existente de notificación de drops y la cobertura de pruebas unitarias relevante. Se considera terminado cuando el estado de los procesos obsoletos se notifica con indicaciones para reiniciarlos y un motivo de drop distinto; el self-healing es opcional siempre que siga siendo fail-open y esté libre de condiciones de carrera.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Problem
QueuedLogDestination starts its listener thread at construction and deliberately carries no fork hooks or pid checks (documented in destinations/queued.py). That is the right simplicity trade-off inside the package, but it moves a correctness obligation onto every consumer whose process forks or restores from a memory snapshot: they must know to call restart_observability() at the right lifecycle moment, after credentials are re-materialized.
The failure mode when a consumer misses this is the worst kind: the service serves traffic normally while every Google-bound record silently drops (reason="full" once the queue fills, dead listener thread never drains). Nothing crashes, nothing alerts on the request path.
We just paid this cost in practice: PolicyEngine/policyengine-household-api#1597 adopts 1.4.0 on Modal, whose workers restore from memory snapshots (@modal.enter(snap=True) builds the app — and with it the queued transport — at snapshot creation). The fix was a restart_observability() call in the post-restore hook, plus a unit test pinning the ordering. The next consumer with a forking or snapshotting runtime (gunicorn --preload with fork, celery prefork, another snapshot platform) has to rediscover all of this from scratch.
Ask
Make dead-listener state detectable — and ideally self-healing — inside the package, so consumers are safe by default rather than safe by convention.
Two tiers, smallest first:
-
Detect and report loudly (minimum).
QueuedLogDestination.emit()already counts drops with a throttled report. Add a cheap staleness check — e.g. compareos.getpid()against the pid captured at construction — and when it differs, report through the internal-error channel with an actionable message namingrestart_observability()and a distinct drop reason (reason="stale-process"rather than"full"). This turns a silent outage into a diagnosable one for the cost of one integer comparison per emit. -
Self-heal (stretch, only if it stays simple). On detecting a stale pid, rebuild the destination the way
restart_log_destinations()does. Constraints that killed the previous attempt at this problem space (#23) still apply and are worth restating: fail-open above all, rebuild fresh clients rather than resurrect old ones, no locking or state machine on the hot path, and no rebuild-inside-emit races — if the rebuild can't be made trivially safe (e.g. singleos.register_at_forkhook rather than emit-path mutation), tier 1 alone is still a big win.
Related prior art: #22 (accept/emit split), #24 (half-open recovery for disabled destinations, closed as deferred), and the consumer-side integration in PolicyEngine/policyengine-household-api#1597.
🤖 Generated with Claude Code
- Lenguaje dominante
- Python
- Estrellas
- 0
- Forks
- 0
- Merge medio
- 7 h 49 min
- PR fusionados (30 d)
- 5
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la 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 PolicyEngine/policyengine-observability
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 30/100
Todos los issues de PolicyEngine/policyengine-observability
Issues similares
-
infrastructure
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
khuisman/mcp-gee-sweet#1152 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
-
backroom bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
ditto-assistant/ditto-subnet#3069 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 67/100
open-webui/open-webui#32901 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
0.3.3 bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día