Hecho con Chinaski

Trabajos en Segundo Plano

Para lotes de contenido muy grandes (cientos de páginas, posts o inserciones de bloques), la API de creación síncrona no es la herramienta adecuada. Chinaski incluye una cola de trabajos: envías una sola solicitud que describe todo el lote, un worker lo procesa elemento por elemento en segundo plano, y tú consultas un único endpoint (o echas un vistazo a la pantalla Jobs del admin) hasta que los contadores se asientan.

Enviar un trabajo

POST /api/jobs con una clave de API con alcance de escritura y un cuerpo JSON de {type, items}:

  • type: exactamente uno de los tres tipos soportados:
    • bulk_upsert_pages: crear o actualizar páginas
    • bulk_upsert_posts: lo mismo para posts
    • bulk_create_blocks: crear bloques nuevos
  • items: un arreglo no vacío de objetos de fila que correspondan al tipo que elegiste.

El endpoint responde de inmediato con {"job_id": "…", "status": "queued"}. Cada elemento se procesa uno tras otro en un worker en segundo plano, de modo que un lote de 5,000 elementos te cuesta una solicitud pequeña en lugar de una gigante.

Forma del elemento (los tres tipos)

Para los upserts de página/post, cada elemento necesita como mínimo:

  • slug + language: el par que identifica al elemento.
  • Si no hay ninguna fila existente que coincida con ese par: también title (obligatorio para la creación), más cualquier otro campo que quieras establecer; solo se respetan las columnas reales de página/post.
  • Si una fila sí existe: cualquier campo proporcionado la actualiza en su lugar, excepto slug y language; esos son la identidad y nunca pueden ser modificados por el trabajo.
  • Los elementos con published=true se crean publicados; todo lo demás queda como borrador hasta que algo lo publique.

Para bloques, los elementos son registros de creación simples (campos tal como los recibe create_block).

Seguir un trabajo

  • Consulta GET /api/jobs/:id (clave de API con alcance de lectura). La forma de la respuesta es fija:
{
  "job_id": "…", "type": "bulk_upsert_pages",
  "status": "queued | running | done | failed",
  "progress": { "total": 500, "done": 312, "errors": 7 },
  "created_at": "…", "updated_at": "…",
  "result": { "completed": 493, "errors": [ … ] }
}
  • Los contadores avanzan en vivo mientras el trabajo corre: done sube (o errors para los elementos que fallaron) en tiempo real; el objeto result aparece exactamente cuando el estado cambia a done.
  • Los fallos a nivel de elemento no hacen fallar el trabajo: la fila sigue adelante, y el resultado final lista cada error junto con el elemento original para que puedas corregir y reenviar solo esas filas.
  • Los estados son literales: un worker que crashea se marca como failed (nunca queda atascado en queued), de modo que el sondeo siempre converge.

Reintentar los elementos fallidos

Los trabajos no se reintentan a sí mismos. Toma el arreglo result.errors del trabajo terminado, corrige las filas que fallan (slugs duplicados, título faltante, idioma bloqueado) y envía un nuevo trabajo que contenga solo esos elementos: la semántica de upsert significa que los elementos ya exitosos simplemente se actualizan de nuevo, de forma idempotente.

La pantalla Jobs del admin

La pantalla Jobs en el admin (solo para Administradores) muestra los 200 trabajos más recientes, los más nuevos primero, con el tipo, los contadores de progreso en vivo y cualquier instantánea de resultado/error, con marcas de tiempo en UTC. Es de solo lectura: recarga para refrescar, y no existen controles de envío ahí; los trabajos son una superficie de API por diseño, así que el sentido de la pantalla es simplemente “¿qué le ha estado haciendo la API a mi contenido?”

Límites que vale conocer

  • Un trabajo no es un build. Los contenidos enviados a través de la API de trabajos escriben registros; el sitio estático sigue reconstruyéndose con sus disparadores habituales. Después de un trabajo grande de bloques/contenido, dispara un build (desde el dashboard o desde la misma API) como parte del mismo paso de automatización.
  • Sin programación. Los trabajos corren inmediatamente después de enviarse; no hay semántica de “retrasar hasta más tarde”; la publicación programada vive en la capa de contenido (ver Scheduling), no en esta cola.
  • Los tipos son fijos. Los tres listados arriba son los únicos tipos de trabajo; las actualizaciones masivas de subconjuntos arbitrarios y otros tipos de entidad tienen sus propios endpoints de bulk de un solo uso en lugar de espacios de tipo de trabajo.
  • El tamaño no tiene tope del lado del servidor. Un trabajo puede llevar cualquier cantidad de elementos (las herramientas de lote como bulk_import se parten a sí mismas en cientos para ser corteses); la cola simplemente va recorriendo la lista.
  • Un fallo especial: si el worker no puede conectarse a la base de datos, el trabajo se marca explícitamente como failed en lugar de quedarse colgado en “queued”, el único tipo de fallo que alcanza ese estado a mitad de camino.

La versión corta

Lote grande = un trabajo: una solicitud (la clave de API con escritura), un par de endpoints para revisar el progreso, tres tipos de contenido que puede crear/actualizar en masa, reporte de errores por elemento, una pantalla de admin con las últimas 200 filas; y recuerda que escribe filas, no sitios: reconstruye cuando tu lote se asiente.

Lee este sitio en