Ir al contenido

Relleno histórico

Ventana de terminal
ghchronicle -config config.yaml -backfill

Una pasada es un incremento. Un relleno histórico es un recorrido. Son intenciones opuestas y la herramienta las trata como tales.

PasadaRelleno
Páginas por colectorel pequeño valor por defecto del colectorhasta que se acabe la API, o hasta el límite dado
Al llegar a la reservasaltar la familia y avisaresperar a que la ventana se reinicie y seguir
Qué familias correnlas que tienen el intervalo vencidotodas las activas, diga lo que diga el fichero de estado
Con qué frecuenciasegún horario, siemprea propósito, normalmente una vez

Una pasada normal nunca debe bloquear. Protege la reserva para que lo demás que use el mismo token siga funcionando, y salta una familia antes que dormir. Un relleno se lanza a propósito y lo único que importa es que termine, así que aparca hasta que el presupuesto vuelva a estar entero. Un relleno que se rinde a medias ha gastado la parte cara del presupuesto y conserva solo las familias que llegó a terminar: cada una se escribe y se marca en cuanto acaba, así que lo que hay que volver a lanzar es el resto.

Cuando un cubo está en su reserva o por debajo, el relleno espera. La espera no se adivina: cada respuesta de GitHub dice exactamente cuándo se reinicia su ventana, así que el colector duerme hasta ese instante más un segundo de holgura y registra lo que está haciendo.

level=INFO msg="rate limit reserve reached, waiting for the window to reset" family=commits wait=23m11s

Dos guardas sobre esa espera. Está limitada a una hora, para que un desfase de reloj o una cabecera obsoleta no se conviertan en un sueño ilimitado, y tiene un suelo de un segundo, para que no se convierta en un bucle activo. Un contexto cancelado termina la espera de inmediato, que es lo que hace que Ctrl+C funcione durante un relleno nocturno.

-backfill-since en la línea de órdenes, o backfill.since en el fichero de configuración. Cuatro formas de escribirlo, porque cada cual tira de una:

ValorSignifica
2024-01-01esa fecha
90dhace noventa días
2yhace dos años
720huna duración de Go antes de ahora
vacío, all, unlimitedsin límite alguno

Sin límite significa que el recorrido solo se detiene donde se detiene la API, por muchas horas o días que eso lleve, con una pausa en cada reinicio de límite por el camino.

Ventana de terminal
ghchronicle -config config.yaml -backfill -backfill-since 2y

Una instalación nueva debería lanzar un relleno antes de arrancar el servicio, o justo después. La primera pasada es un incremento más ancho, no una historia: un mes de ejecuciones de workflows, la historia de estrellas entera y la página más reciente de todo lo demás. Los puntos van fechados, así que a cualquier almacén le vale; a un dashboard a noventa días o a dos años no, porque la historia que dibuja empieza el día en que se instaló el colector.

Medido tras un día de pasadas y sin relleno, sobre repositorios con cientos de pull requests cada uno: pull requests, alrededor de una quinta parte de las que declaran los repositorios, porque una pasada lee una sola página de cincuenta por repositorio por muchas que tenga; issues, alrededor de la mitad; commits, bastante menos de una décima parte y ninguno de más de treinta días; jobs y pasos de una décima parte de las ejecuciones de workflows, así que la espera en cola, los jobs más lentos y los pasos que fallan se calcularon sobre esa décima parte. A dos años, Pull requests merged marcaba una quinta parte de lo que decía Pull requests merged, ever. Estrellas, forks, releases, despliegues y alertas estaban completos, porque la primera pasada los recorre hasta el final de todos modos.

  • Toda la historia de commits, en lugar de la última página. Esta es la única familia en la que un relleno es cualitativamente distinto y no solo más ancho: sin él la serie de líneas cambiadas empieza el día en que instalaste el colector.
  • Dos años de ejecuciones de workflows, y cada ejecución expandida en sus jobs y sus pasos.
  • Los repositorios archivados, enteros, diga lo que diga include_archived. Su historia es la historia de la cuenta y ya no se mueve, que es justo por lo que una pasada los deja fuera y por lo que un solo recorrido basta. Los forks quedan como estén configurados. Una pasada sigue escribiendo la única fila que tiene cada repositorio archivado, la fecha en que se archivó: el listado que ya paga dice cuáles, y una consulta por pasada de totals dice cuándo.
  • Todas las páginas de artefactos, veinte páginas de actividad del repositorio y los análisis de code scanning.
  • Cien pull requests e issues por repositorio.
  • Las notificaciones leídas además de las no leídas.
  • Veinticuatro meses de facturación.
  • Cien entregas de webhook por hook.

Un relleno corre todas las familias activas diga lo que diga el fichero de estado. No enciende ninguna. Las tres familias que vienen con cadencia 0, deps, history y joblogs, siguen apagadas si no se les ha dado una por nombre bajo every.families, y -backfill no cambia eso.

history es la que sorprende, porque recorrer cada año pasado del calendario de contribuciones es justo lo que tiene en la cabeza quien pide “toda la historia”. Dale antes una cadencia:

every:
families:
history: 24h

En cadencias está por qué default y groups tampoco pueden encender estas tres.

Ambos se descubrieron ejecutándolo, no leyendo documentación.

Dependabot rechaza los números de página. Responde con un error a page= sin más y pagina por cursor, así que el recorrido de alertas está escrito contra cursores.

La pasarela de GraphQL se rinde con cien pull requests. Pedir cien pull requests con sus revisiones en una consulta responde un 502 en HTML al cabo de unos diez segundos. El recorrido de pull requests parte su página por la mitad y reintenta sobre el mismo cursor, en silencio: los colectores no llevan registrador, así que un relleno de un repositorio activo lo muestra solo como una familia más lenta, nunca como una línea.

Es idempotente. Los puntos se indexan por medida, etiquetas y marca de tiempo, así que un relleno ejecutado dos veces reescribe las mismas filas en vez de duplicarlas, en todo almacén que guarde la historia. Lo que cuesta es cuota de API y tiempo.

Dos cosas que conviene hacer antes: ejecutar -list para confirmar el conjunto de repositorios, y comprobar que el almacén al que escribes es de los que guardan fechas. Rellenar hacia Prometheus recoge muchísima historia y después la reduce entera a un único valor actual.